Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf54106f

Browse files
committed
Fix full-table-vacuum request mechanism for MultiXactIds
While autovacuum dutifully launched anti-multixact-wraparound vacuumswhen the multixact "age" was reached, the vacuum code was not aware thatit needed to make them be full table vacuums. As the resultingpartial-table vacuums aren't capable of actually increasing relminmxid,autovacuum continued to launch anti-wraparound vacuums that didn't havethe intended effect, until age of relfrozenxid caused the vacuum tofinally be a full table one via vacuum_freeze_table_age.To fix, introduce logic for multixacts similar to that for plainTransactionIds, using the same GUCs.Backpatch to 9.3, where permanent MultiXactIds were introduced.Andres Freund, some cleanup by Álvaro
1 parent76a31c6 commitf54106f

File tree

6 files changed

+87
-28
lines changed

6 files changed

+87
-28
lines changed

‎src/backend/access/transam/multixact.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,6 +2374,21 @@ MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
23742374
return (diff<0);
23752375
}
23762376

2377+
/*
2378+
* MultiXactIdPrecedesOrEquals -- is multi1 logically <= multi2?
2379+
*
2380+
* XXX do we need to do something special for InvalidMultiXactId?
2381+
* (Doesn't look like it.)
2382+
*/
2383+
bool
2384+
MultiXactIdPrecedesOrEquals(MultiXactIdmulti1,MultiXactIdmulti2)
2385+
{
2386+
int32diff= (int32) (multi1-multi2);
2387+
2388+
return (diff <=0);
2389+
}
2390+
2391+
23772392
/*
23782393
* Decide which of two offsets is earlier.
23792394
*/

‎src/backend/commands/cluster.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
176176
/* close relation, keep lock till commit */
177177
heap_close(rel,NoLock);
178178

179-
/* Do the job */
179+
/*
180+
* Do the job. We use a -1 freeze_min_age to avoid having CLUSTER
181+
* freeze tuples earlier than a plain VACUUM would.
182+
*/
180183
cluster_rel(tableOid,indexOid, false,stmt->verbose,-1,-1);
181184
}
182185
else
@@ -226,6 +229,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
226229
StartTransactionCommand();
227230
/* functions in indexes may want a snapshot set */
228231
PushActiveSnapshot(GetTransactionSnapshot());
232+
/* Do the job. As above, use a -1 freeze_min_age. */
229233
cluster_rel(rvtc->tableOid,rvtc->indexOid, true,stmt->verbose,
230234
-1,-1);
231235
PopActiveSnapshot();
@@ -853,13 +857,12 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
853857
*pSwapToastByContent= false;
854858

855859
/*
856-
* compute xids used to freeze and weed out dead tuples. We use -1
857-
* freeze_min_age to avoid having CLUSTER freeze tuples earlier than a
858-
* plain VACUUM would.
860+
* compute xids used to freeze and weed out dead tuples.
859861
*/
860862
vacuum_set_xid_limits(freeze_min_age,freeze_table_age,
861863
OldHeap->rd_rel->relisshared,
862-
&OldestXmin,&FreezeXid,NULL,&MultiXactCutoff);
864+
&OldestXmin,&FreezeXid,NULL,&MultiXactCutoff,
865+
NULL);
863866

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

‎src/backend/commands/vacuum.c

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -376,19 +376,39 @@ get_rel_oids(Oid relid, const RangeVar *vacrel)
376376

377377
/*
378378
* vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
379+
*
380+
* The output parameters are:
381+
* - oldestXmin is the cutoff value used to distinguish whether tuples are
382+
* DEAD or RECENTLY_DEAD (see HeapTupleSatisfiesVacuum).
383+
* - freezeLimit is the Xid below which all Xids are replaced by
384+
* FrozenTransactionId during vacuum.
385+
* - xidFullScanLimit (computed from the the table_freeze_age parameter)
386+
* represents a minimum Xid value; a table whose relfrozenxid is older than
387+
* this will have a full-table vacuum applied to it, to freeze tuples across
388+
* the whole table. Vacuuming a table younger than this value can use a
389+
* partial scan.
390+
* - multiXactCutoff is the value below which all MultiXactIds are removed from
391+
* Xmax.
392+
* - mxactFullScanLimit is a value against which a table's relminmxid value is
393+
* compared to produce a full-table vacuum, as with xidFullScanLimit.
394+
*
395+
* xidFullScanLimit and mxactFullScanLimit can be passed as NULL if caller is
396+
* not interested.
379397
*/
380398
void
381399
vacuum_set_xid_limits(intfreeze_min_age,
382400
intfreeze_table_age,
383401
boolsharedRel,
384402
TransactionId*oldestXmin,
385403
TransactionId*freezeLimit,
386-
TransactionId*freezeTableLimit,
387-
MultiXactId*multiXactCutoff)
404+
TransactionId*xidFullScanLimit,
405+
MultiXactId*multiXactCutoff,
406+
MultiXactId*mxactFullScanLimit)
388407
{
389408
intfreezemin;
390409
TransactionIdlimit;
391410
TransactionIdsafeLimit;
411+
MultiXactIdmxactLimit;
392412

393413
/*
394414
* We can always ignore processes running lazy vacuum.This is because we
@@ -441,10 +461,22 @@ vacuum_set_xid_limits(int freeze_min_age,
441461

442462
*freezeLimit=limit;
443463

444-
if (freezeTableLimit!=NULL)
464+
/*
465+
* simplistic MultiXactId removal limit: use the same policy as for
466+
* freezing Xids (except we use the oldest known mxact instead of the
467+
* current next value).
468+
*/
469+
mxactLimit=GetOldestMultiXactId()-freezemin;
470+
if (mxactLimit<FirstMultiXactId)
471+
mxactLimit=FirstMultiXactId;
472+
*multiXactCutoff=mxactLimit;
473+
474+
if (xidFullScanLimit!=NULL)
445475
{
446476
intfreezetable;
447477

478+
Assert(mxactFullScanLimit!=NULL);
479+
448480
/*
449481
* Determine the table freeze age to use: as specified by the caller,
450482
* or vacuum_freeze_table_age, but in any case not more than
@@ -459,29 +491,25 @@ vacuum_set_xid_limits(int freeze_min_age,
459491
Assert(freezetable >=0);
460492

461493
/*
462-
* Computethe cutoff XID, being careful not to generate a "permanent"
463-
* XID.
494+
* ComputeXID limit causing a full-table vacuum, being careful not to
495+
*generate a "permanent"XID.
464496
*/
465497
limit=ReadNewTransactionId()-freezetable;
466498
if (!TransactionIdIsNormal(limit))
467499
limit=FirstNormalTransactionId;
468500

469-
*freezeTableLimit=limit;
470-
}
471-
472-
if (multiXactCutoff!=NULL)
473-
{
474-
MultiXactIdmxLimit;
501+
*xidFullScanLimit=limit;
475502

476503
/*
477-
* simplistic multixactid freezing: use the same freezing policy as
478-
* for Xids
504+
* Compute MultiXactId limit to cause a full-table vacuum, being
505+
* careful not to generate an invalid multi. We just copy the logic
506+
* (and limits) from plain XIDs here.
479507
*/
480-
mxLimit=GetOldestMultiXactId()-freezemin;
481-
if (mxLimit<FirstMultiXactId)
482-
mxLimit=FirstMultiXactId;
508+
mxactLimit=ReadNextMultiXactId()-freezetable;
509+
if (mxactLimit<FirstMultiXactId)
510+
mxactLimit=FirstMultiXactId;
483511

484-
*multiXactCutoff=mxLimit;
512+
*mxactFullScanLimit=mxactLimit;
485513
}
486514
}
487515

‎src/backend/commands/vacuumlazy.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
180180
write_rate;
181181
boolscan_all;/* should we scan all pages? */
182182
boolscanned_all;/* did we actually scan all pages? */
183-
TransactionIdfreezeTableLimit;
183+
TransactionIdxidFullScanLimit;
184+
MultiXactIdmxactFullScanLimit;
184185
BlockNumbernew_rel_pages;
185186
doublenew_rel_tuples;
186187
BlockNumbernew_rel_allvisible;
@@ -203,10 +204,19 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
203204

204205
vacuum_set_xid_limits(vacstmt->freeze_min_age,vacstmt->freeze_table_age,
205206
onerel->rd_rel->relisshared,
206-
&OldestXmin,&FreezeLimit,&freezeTableLimit,
207-
&MultiXactCutoff);
207+
&OldestXmin,&FreezeLimit,&xidFullScanLimit,
208+
&MultiXactCutoff,&mxactFullScanLimit);
209+
210+
/*
211+
* We request a full scan if either the table's frozen Xid is now older
212+
* than or equal to the requested Xid full-table scan limit; or if the
213+
* table's minimum MultiXactId is older than or equal to the requested mxid
214+
* full-table scan limit.
215+
*/
208216
scan_all=TransactionIdPrecedesOrEquals(onerel->rd_rel->relfrozenxid,
209-
freezeTableLimit);
217+
xidFullScanLimit);
218+
scan_all |=MultiXactIdPrecedesOrEquals(onerel->rd_rel->relminmxid,
219+
mxactFullScanLimit);
210220

211221
vacrelstats= (LVRelStats*)palloc0(sizeof(LVRelStats));
212222

‎src/include/access/multixact.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ extern void MultiXactIdSetOldestMember(void);
8787
externintGetMultiXactIdMembers(MultiXactIdmulti,MultiXactMember**xids,
8888
boolallow_old);
8989
externboolMultiXactIdPrecedes(MultiXactIdmulti1,MultiXactIdmulti2);
90+
externboolMultiXactIdPrecedesOrEquals(MultiXactIdmulti1,
91+
MultiXactIdmulti2);
9092

9193
externvoidAtEOXact_MultiXact(void);
9294
externvoidAtPrepare_MultiXact(void);

‎src/include/commands/vacuum.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,9 @@ extern void vacuum_set_xid_limits(int freeze_min_age, int freeze_table_age,
159159
boolsharedRel,
160160
TransactionId*oldestXmin,
161161
TransactionId*freezeLimit,
162-
TransactionId*freezeTableLimit,
163-
MultiXactId*multiXactCutoff);
162+
TransactionId*xidFullScanLimit,
163+
MultiXactId*multiXactCutoff,
164+
MultiXactId*mxactFullScanLimit);
164165
externvoidvac_update_datfrozenxid(void);
165166
externvoidvacuum_delay_point(void);
166167

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp