Skip to content

Commit efa4a94

Browse files
Consolidate VACUUM xid cutoff logic.
Push the logic for determining whether or not a VACUUM operation will be aggressive down into vacuum_set_xid_limits(). This makes the function's signature significantly simpler, and seems clearer overall. Author: Peter Geoghegan <pg@bowt.ie> Discussion: https://postgr.es/m/CAH2-WzkymFbz6D_vL+jmqSn_5q1wsFvFrE+37yLgL_Rkfd6Gzg@mail.gmail.com
1 parent 872770f commit efa4a94

File tree

4 files changed

+79
-95
lines changed

4 files changed

+79
-95
lines changed

src/backend/access/heap/vacuumlazy.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,6 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
323323
minmulti_updated;
324324
BlockNumber orig_rel_pages;
325325
char **indnames = NULL;
326-
TransactionId xidFullScanLimit;
327-
MultiXactId mxactFullScanLimit;
328326
BlockNumber new_rel_pages;
329327
BlockNumber new_rel_allvisible;
330328
double new_live_tuples;
@@ -352,24 +350,24 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
352350
pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM,
353351
RelationGetRelid(rel));
354352

355-
vacuum_set_xid_limits(rel,
356-
params->freeze_min_age,
357-
params->freeze_table_age,
358-
params->multixact_freeze_min_age,
359-
params->multixact_freeze_table_age,
360-
&OldestXmin, &FreezeLimit, &xidFullScanLimit,
361-
&MultiXactCutoff, &mxactFullScanLimit);
362-
363353
/*
364-
* We request an aggressive scan if the table's frozen Xid is now older
365-
* than or equal to the requested Xid full-table scan limit; or if the
366-
* table's minimum MultiXactId is older than or equal to the requested
367-
* mxid full-table scan limit; or if DISABLE_PAGE_SKIPPING was specified.
354+
* Get OldestXmin cutoff, which is used to determine which deleted tuples
355+
* are considered DEAD, not just RECENTLY_DEAD. Also get related cutoffs
356+
* used to determine which XIDs/MultiXactIds will be frozen.
357+
*
358+
* If this is an aggressive VACUUM, then we're strictly required to freeze
359+
* any and all XIDs from before FreezeLimit, so that we will be able to
360+
* safely advance relfrozenxid up to FreezeLimit below (we must be able to
361+
* advance relminmxid up to MultiXactCutoff, too).
368362
*/
369-
aggressive = TransactionIdPrecedesOrEquals(rel->rd_rel->relfrozenxid,
370-
xidFullScanLimit);
371-
aggressive |= MultiXactIdPrecedesOrEquals(rel->rd_rel->relminmxid,
372-
mxactFullScanLimit);
363+
aggressive = vacuum_set_xid_limits(rel,
364+
params->freeze_min_age,
365+
params->freeze_table_age,
366+
params->multixact_freeze_min_age,
367+
params->multixact_freeze_table_age,
368+
&OldestXmin, &FreezeLimit,
369+
&MultiXactCutoff);
370+
373371
skipwithvm = true;
374372
if (params->options & VACOPT_DISABLE_PAGE_SKIPPING)
375373
{

src/backend/commands/cluster.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -857,8 +857,7 @@ copy_table_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
857857
* not to be aggressive about this.
858858
*/
859859
vacuum_set_xid_limits(OldHeap, 0, 0, 0, 0,
860-
&OldestXmin, &FreezeXid, NULL, &MultiXactCutoff,
861-
NULL);
860+
&OldestXmin, &FreezeXid, &MultiXactCutoff);
862861

863862
/*
864863
* FreezeXid will become the table's new relfrozenxid, and that mustn't go

src/backend/commands/vacuum.c

Lines changed: 60 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -943,34 +943,26 @@ get_all_vacuum_rels(int options)
943943
* Input parameters are the target relation, applicable freeze age settings.
944944
*
945945
* The output parameters are:
946-
* - oldestXmin is the cutoff value used to distinguish whether tuples are
947-
* DEAD or RECENTLY_DEAD (see HeapTupleSatisfiesVacuum).
946+
* - oldestXmin is the Xid below which tuples deleted by any xact (that
947+
* committed) should be considered DEAD, not just RECENTLY_DEAD.
948948
* - freezeLimit is the Xid below which all Xids are replaced by
949949
* FrozenTransactionId during vacuum.
950-
* - xidFullScanLimit (computed from freeze_table_age parameter)
951-
* represents a minimum Xid value; a table whose relfrozenxid is older than
952-
* this will have a full-table vacuum applied to it, to freeze tuples across
953-
* the whole table. Vacuuming a table younger than this value can use a
954-
* partial scan.
955-
* - multiXactCutoff is the value below which all MultiXactIds are removed from
956-
* Xmax.
957-
* - mxactFullScanLimit is a value against which a table's relminmxid value is
958-
* compared to produce a full-table vacuum, as with xidFullScanLimit.
950+
* - multiXactCutoff is the value below which all MultiXactIds are removed
951+
* from Xmax.
959952
*
960-
* xidFullScanLimit and mxactFullScanLimit can be passed as NULL if caller is
961-
* not interested.
953+
* Return value indicates if vacuumlazy.c caller should make its VACUUM
954+
* operation aggressive. An aggressive VACUUM must advance relfrozenxid up to
955+
* FreezeLimit, and relminmxid up to multiXactCutoff.
962956
*/
963-
void
957+
bool
964958
vacuum_set_xid_limits(Relation rel,
965959
int freeze_min_age,
966960
int freeze_table_age,
967961
int multixact_freeze_min_age,
968962
int multixact_freeze_table_age,
969963
TransactionId *oldestXmin,
970964
TransactionId *freezeLimit,
971-
TransactionId *xidFullScanLimit,
972-
MultiXactId *multiXactCutoff,
973-
MultiXactId *mxactFullScanLimit)
965+
MultiXactId *multiXactCutoff)
974966
{
975967
int freezemin;
976968
int mxid_freezemin;
@@ -980,6 +972,7 @@ vacuum_set_xid_limits(Relation rel,
980972
MultiXactId oldestMxact;
981973
MultiXactId mxactLimit;
982974
MultiXactId safeMxactLimit;
975+
int freezetable;
983976

984977
/*
985978
* We can always ignore processes running lazy vacuum. This is because we
@@ -1097,64 +1090,60 @@ vacuum_set_xid_limits(Relation rel,
10971090

10981091
*multiXactCutoff = mxactLimit;
10991092

1100-
if (xidFullScanLimit != NULL)
1101-
{
1102-
int freezetable;
1103-
1104-
Assert(mxactFullScanLimit != NULL);
1105-
1106-
/*
1107-
* Determine the table freeze age to use: as specified by the caller,
1108-
* or vacuum_freeze_table_age, but in any case not more than
1109-
* autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
1110-
* VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
1111-
* before anti-wraparound autovacuum is launched.
1112-
*/
1113-
freezetable = freeze_table_age;
1114-
if (freezetable < 0)
1115-
freezetable = vacuum_freeze_table_age;
1116-
freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
1117-
Assert(freezetable >= 0);
1118-
1119-
/*
1120-
* Compute XID limit causing a full-table vacuum, being careful not to
1121-
* generate a "permanent" XID.
1122-
*/
1123-
limit = ReadNextTransactionId() - freezetable;
1124-
if (!TransactionIdIsNormal(limit))
1125-
limit = FirstNormalTransactionId;
1093+
/*
1094+
* Done setting output parameters; just need to figure out if caller needs
1095+
* to do an aggressive VACUUM or not.
1096+
*
1097+
* Determine the table freeze age to use: as specified by the caller, or
1098+
* vacuum_freeze_table_age, but in any case not more than
1099+
* autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
1100+
* VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
1101+
* before anti-wraparound autovacuum is launched.
1102+
*/
1103+
freezetable = freeze_table_age;
1104+
if (freezetable < 0)
1105+
freezetable = vacuum_freeze_table_age;
1106+
freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
1107+
Assert(freezetable >= 0);
11261108

1127-
*xidFullScanLimit = limit;
1109+
/*
1110+
* Compute XID limit causing an aggressive vacuum, being careful not to
1111+
* generate a "permanent" XID
1112+
*/
1113+
limit = ReadNextTransactionId() - freezetable;
1114+
if (!TransactionIdIsNormal(limit))
1115+
limit = FirstNormalTransactionId;
1116+
if (TransactionIdPrecedesOrEquals(rel->rd_rel->relfrozenxid,
1117+
limit))
1118+
return true;
11281119

1129-
/*
1130-
* Similar to the above, determine the table freeze age to use for
1131-
* multixacts: as specified by the caller, or
1132-
* vacuum_multixact_freeze_table_age, but in any case not more than
1133-
* autovacuum_multixact_freeze_table_age * 0.95, so that if you have
1134-
* e.g. nightly VACUUM schedule, the nightly VACUUM gets a chance to
1135-
* freeze multixacts before anti-wraparound autovacuum is launched.
1136-
*/
1137-
freezetable = multixact_freeze_table_age;
1138-
if (freezetable < 0)
1139-
freezetable = vacuum_multixact_freeze_table_age;
1140-
freezetable = Min(freezetable,
1141-
effective_multixact_freeze_max_age * 0.95);
1142-
Assert(freezetable >= 0);
1120+
/*
1121+
* Similar to the above, determine the table freeze age to use for
1122+
* multixacts: as specified by the caller, or
1123+
* vacuum_multixact_freeze_table_age, but in any case not more than
1124+
* autovacuum_multixact_freeze_table_age * 0.95, so that if you have e.g.
1125+
* nightly VACUUM schedule, the nightly VACUUM gets a chance to freeze
1126+
* multixacts before anti-wraparound autovacuum is launched.
1127+
*/
1128+
freezetable = multixact_freeze_table_age;
1129+
if (freezetable < 0)
1130+
freezetable = vacuum_multixact_freeze_table_age;
1131+
freezetable = Min(freezetable,
1132+
effective_multixact_freeze_max_age * 0.95);
1133+
Assert(freezetable >= 0);
11431134

1144-
/*
1145-
* Compute MultiXact limit causing a full-table vacuum, being careful
1146-
* to generate a valid MultiXact value.
1147-
*/
1148-
mxactLimit = ReadNextMultiXactId() - freezetable;
1149-
if (mxactLimit < FirstMultiXactId)
1150-
mxactLimit = FirstMultiXactId;
1135+
/*
1136+
* Compute MultiXact limit causing an aggressive vacuum, being careful to
1137+
* generate a valid MultiXact value
1138+
*/
1139+
mxactLimit = ReadNextMultiXactId() - freezetable;
1140+
if (mxactLimit < FirstMultiXactId)
1141+
mxactLimit = FirstMultiXactId;
1142+
if (MultiXactIdPrecedesOrEquals(rel->rd_rel->relminmxid,
1143+
mxactLimit))
1144+
return true;
11511145

1152-
*mxactFullScanLimit = mxactLimit;
1153-
}
1154-
else
1155-
{
1156-
Assert(mxactFullScanLimit == NULL);
1157-
}
1146+
return false;
11581147
}
11591148

11601149
/*

src/include/commands/vacuum.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,15 +286,13 @@ extern void vac_update_relstats(Relation relation,
286286
bool *frozenxid_updated,
287287
bool *minmulti_updated,
288288
bool in_outer_xact);
289-
extern void vacuum_set_xid_limits(Relation rel,
289+
extern bool vacuum_set_xid_limits(Relation rel,
290290
int freeze_min_age, int freeze_table_age,
291291
int multixact_freeze_min_age,
292292
int multixact_freeze_table_age,
293293
TransactionId *oldestXmin,
294294
TransactionId *freezeLimit,
295-
TransactionId *xidFullScanLimit,
296-
MultiXactId *multiXactCutoff,
297-
MultiXactId *mxactFullScanLimit);
295+
MultiXactId *multiXactCutoff);
298296
extern bool vacuum_xid_failsafe_check(TransactionId relfrozenxid,
299297
MultiXactId relminmxid);
300298
extern void vac_update_datfrozenxid(void);

0 commit comments

Comments
 (0)