diff options
Diffstat (limited to 'src/backend/commands/vacuum.c')
-rw-r--r-- | src/backend/commands/vacuum.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 25465b05ddb..39df05c7352 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -62,6 +62,8 @@ int vacuum_freeze_min_age; int vacuum_freeze_table_age; int vacuum_multixact_freeze_min_age; int vacuum_multixact_freeze_table_age; +int vacuum_failsafe_age; +int vacuum_multixact_failsafe_age; /* A few variables that don't seem worth passing around as parameters */ @@ -1135,6 +1137,62 @@ vacuum_set_xid_limits(Relation rel, } /* + * vacuum_xid_failsafe_check() -- Used by VACUUM's wraparound failsafe + * mechanism to determine if its table's relfrozenxid and relminmxid are now + * dangerously far in the past. + * + * Input parameters are the target relation's relfrozenxid and relminmxid. + * + * When we return true, VACUUM caller triggers the failsafe. + */ +bool +vacuum_xid_failsafe_check(TransactionId relfrozenxid, MultiXactId relminmxid) +{ + TransactionId xid_skip_limit; + MultiXactId multi_skip_limit; + int skip_index_vacuum; + + Assert(TransactionIdIsNormal(relfrozenxid)); + Assert(MultiXactIdIsValid(relminmxid)); + + /* + * Determine the index skipping age to use. In any case no less than + * autovacuum_freeze_max_age * 1.05. + */ + skip_index_vacuum = Max(vacuum_failsafe_age, autovacuum_freeze_max_age * 1.05); + + xid_skip_limit = ReadNextTransactionId() - skip_index_vacuum; + if (!TransactionIdIsNormal(xid_skip_limit)) + xid_skip_limit = FirstNormalTransactionId; + + if (TransactionIdPrecedes(relfrozenxid, xid_skip_limit)) + { + /* The table's relfrozenxid is too old */ + return true; + } + + /* + * Similar to above, determine the index skipping age to use for + * multixact. In any case no less than autovacuum_multixact_freeze_max_age + * * 1.05. + */ + skip_index_vacuum = Max(vacuum_multixact_failsafe_age, + autovacuum_multixact_freeze_max_age * 1.05); + + multi_skip_limit = ReadNextMultiXactId() - skip_index_vacuum; + if (multi_skip_limit < FirstMultiXactId) + multi_skip_limit = FirstMultiXactId; + + if (MultiXactIdPrecedes(relminmxid, multi_skip_limit)) + { + /* The table's relminmxid is too old */ + return true; + } + + return false; +} + +/* * vac_estimate_reltuples() -- estimate the new value for pg_class.reltuples * * If we scanned the whole relation then we should just use the count of |