mirror of
https://github.com/postgres/postgres.git
synced 2025-08-30 06:01:21 +03:00
Teach autovacuum about multixact member wraparound.
The logic introduced in commitb69bf30b9b
and repaired in commits669c7d20e6
and7be47c56af
helps to ensure that we don't overwrite old multixact member information while it is still needed, but a user who creates many large multixacts can still exhaust the member space (and thus start getting errors) while autovacuum stands idly by. To fix this, progressively ramp down the effective value (but not the actual contents) of autovacuum_multixact_freeze_max_age as member space utilization increases. This makes autovacuum more aggressive and also reduces the threshold for a manual VACUUM to perform a full-table scan. This patch leaves unsolved the problem of ensuring that emergency autovacuums are triggered even when autovacuum=off. We'll need to fix that via a separate patch. Thomas Munro and Robert Haas
This commit is contained in:
@@ -426,6 +426,7 @@ vacuum_set_xid_limits(int freeze_min_age,
|
||||
{
|
||||
int freezemin;
|
||||
int mxid_freezemin;
|
||||
int effective_multixact_freeze_max_age;
|
||||
TransactionId limit;
|
||||
TransactionId safeLimit;
|
||||
MultiXactId mxactLimit;
|
||||
@@ -482,17 +483,24 @@ vacuum_set_xid_limits(int freeze_min_age,
|
||||
|
||||
*freezeLimit = limit;
|
||||
|
||||
/*
|
||||
* Compute the multixact age for which freezing is urgent. This is
|
||||
* normally autovacuum_multixact_freeze_max_age, but may be less if we
|
||||
* are short of multixact member space.
|
||||
*/
|
||||
effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
|
||||
|
||||
/*
|
||||
* Determine the minimum multixact freeze age to use: as specified by
|
||||
* caller, or vacuum_multixact_freeze_min_age, but in any case not more
|
||||
* than half autovacuum_multixact_freeze_max_age, so that autovacuums to
|
||||
* than half effective_multixact_freeze_max_age, so that autovacuums to
|
||||
* prevent MultiXact wraparound won't occur too frequently.
|
||||
*/
|
||||
mxid_freezemin = multixact_freeze_min_age;
|
||||
if (mxid_freezemin < 0)
|
||||
mxid_freezemin = vacuum_multixact_freeze_min_age;
|
||||
mxid_freezemin = Min(mxid_freezemin,
|
||||
autovacuum_multixact_freeze_max_age / 2);
|
||||
effective_multixact_freeze_max_age / 2);
|
||||
Assert(mxid_freezemin >= 0);
|
||||
|
||||
/* compute the cutoff multi, being careful to generate a valid value */
|
||||
@@ -501,7 +509,7 @@ vacuum_set_xid_limits(int freeze_min_age,
|
||||
mxactLimit = FirstMultiXactId;
|
||||
|
||||
safeMxactLimit =
|
||||
ReadNextMultiXactId() - autovacuum_multixact_freeze_max_age;
|
||||
ReadNextMultiXactId() - effective_multixact_freeze_max_age;
|
||||
if (safeMxactLimit < FirstMultiXactId)
|
||||
safeMxactLimit = FirstMultiXactId;
|
||||
|
||||
@@ -556,7 +564,7 @@ vacuum_set_xid_limits(int freeze_min_age,
|
||||
if (freezetable < 0)
|
||||
freezetable = vacuum_multixact_freeze_table_age;
|
||||
freezetable = Min(freezetable,
|
||||
autovacuum_multixact_freeze_max_age * 0.95);
|
||||
effective_multixact_freeze_max_age * 0.95);
|
||||
Assert(freezetable >= 0);
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user