mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Separate multixact freezing parameters from xid's
Previously we were piggybacking on transaction ID parameters to freeze multixacts; but since there isn't necessarily any relationship between rates of Xid and multixact consumption, this turns out not to be a good idea. Therefore, we now have multixact-specific freezing parameters: vacuum_multixact_freeze_min_age: when to remove multis as we come across them in vacuum (default to 5 million, i.e. early in comparison to Xid's default of 50 million) vacuum_multixact_freeze_table_age: when to force whole-table scans instead of scanning only the pages marked as not all visible in visibility map (default to 150 million, same as for Xids). Whichever of both which reaches the 150 million mark earlier will cause a whole-table scan. autovacuum_multixact_freeze_max_age: when for cause emergency, uninterruptible whole-table scans (default to 400 million, double as that for Xids). This means there shouldn't be more frequent emergency vacuuming than previously, unless multixacts are being used very rapidly. Backpatch to 9.3 where multixacts were made to persist enough to require freezing. To avoid an ABI break in 9.3, VacuumStmt has a couple of fields in an unnatural place, and StdRdOptions is split in two so that the newly added fields can go at the end. Patch by me, reviewed by Robert Haas, with additional input from Andres Freund and Tom Lane.
This commit is contained in:
@ -2055,11 +2055,13 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
|
||||
Assert(MultiXactIdIsValid(oldest_datminmxid));
|
||||
|
||||
/*
|
||||
* The place where we actually get into deep trouble is halfway around
|
||||
* from the oldest potentially-existing XID/multi. (This calculation is
|
||||
* probably off by one or two counts for Xids, because the special XIDs
|
||||
* reduce the size of the loop a little bit. But we throw in plenty of
|
||||
* slop below, so it doesn't matter.)
|
||||
* Since multixacts wrap differently from transaction IDs, this logic is
|
||||
* not entirely correct: in some scenarios we could go for longer than 2
|
||||
* billion multixacts without seeing any data loss, and in some others we
|
||||
* could get in trouble before that if the new pg_multixact/members data
|
||||
* stomps on the previous cycle's data. For lack of a better mechanism we
|
||||
* use the same logic as for transaction IDs, that is, start taking action
|
||||
* halfway around the oldest potentially-existing multixact.
|
||||
*/
|
||||
multiWrapLimit = oldest_datminmxid + (MaxMultiXactId >> 1);
|
||||
if (multiWrapLimit < FirstMultiXactId)
|
||||
@ -2093,12 +2095,13 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid)
|
||||
|
||||
/*
|
||||
* We'll start trying to force autovacuums when oldest_datminmxid gets to
|
||||
* be more than autovacuum_freeze_max_age mxids old.
|
||||
* be more than autovacuum_multixact_freeze_max_age mxids old.
|
||||
*
|
||||
* It's a bit ugly to just reuse limits for xids that way, but it doesn't
|
||||
* seem worth adding separate GUCs for that purpose.
|
||||
* Note: autovacuum_multixact_freeze_max_age is a PGC_POSTMASTER parameter
|
||||
* so that we don't have to worry about dealing with on-the-fly changes in
|
||||
* its value. See SetTransactionIdLimit.
|
||||
*/
|
||||
multiVacLimit = oldest_datminmxid + autovacuum_freeze_max_age;
|
||||
multiVacLimit = oldest_datminmxid + autovacuum_multixact_freeze_max_age;
|
||||
if (multiVacLimit < FirstMultiXactId)
|
||||
multiVacLimit += FirstMultiXactId;
|
||||
|
||||
|
Reference in New Issue
Block a user