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

Commit7c5915c

Browse files
committed
Close race condition between datfrozen and relfrozen updates.
vac_update_datfrozenxid() did multiple loads of relfrozenxid andrelminmxid from buffer memory, and it assumed each would get the samevalue. Not so if a concurrent vac_update_relstats() did an inplaceupdate. Commit2d2e40e fixed the samekind of bug in vac_truncate_clog(). Today's bug could cause therel-level field and XIDs in the rel's rows to precede the db-levelfield. A cluster having such values should VACUUM affected tables.Back-patch to v12 (all supported versions).Discussion:https://postgr.es/m/20240423003956.e7.nmisch@google.com
1 parent9b41d1d commit7c5915c

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,8 @@ vac_update_datfrozenxid(void)
15321532
/*
15331533
* We must seqscan pg_class to find the minimum Xid, because there is no
15341534
* index that can help us here.
1535+
*
1536+
* See vac_truncate_clog() for the race condition to prevent.
15351537
*/
15361538
relation=table_open(RelationRelationId,AccessShareLock);
15371539

@@ -1540,7 +1542,9 @@ vac_update_datfrozenxid(void)
15401542

15411543
while ((classTup=systable_getnext(scan))!=NULL)
15421544
{
1543-
Form_pg_classclassForm= (Form_pg_class)GETSTRUCT(classTup);
1545+
volatileFormData_pg_class*classForm= (Form_pg_class)GETSTRUCT(classTup);
1546+
TransactionIdrelfrozenxid=classForm->relfrozenxid;
1547+
TransactionIdrelminmxid=classForm->relminmxid;
15441548

15451549
/*
15461550
* Only consider relations able to hold unfrozen XIDs (anything else
@@ -1550,8 +1554,8 @@ vac_update_datfrozenxid(void)
15501554
classForm->relkind!=RELKIND_MATVIEW&&
15511555
classForm->relkind!=RELKIND_TOASTVALUE)
15521556
{
1553-
Assert(!TransactionIdIsValid(classForm->relfrozenxid));
1554-
Assert(!MultiXactIdIsValid(classForm->relminmxid));
1557+
Assert(!TransactionIdIsValid(relfrozenxid));
1558+
Assert(!MultiXactIdIsValid(relminmxid));
15551559
continue;
15561560
}
15571561

@@ -1570,34 +1574,34 @@ vac_update_datfrozenxid(void)
15701574
* before those relations have been scanned and cleaned up.
15711575
*/
15721576

1573-
if (TransactionIdIsValid(classForm->relfrozenxid))
1577+
if (TransactionIdIsValid(relfrozenxid))
15741578
{
1575-
Assert(TransactionIdIsNormal(classForm->relfrozenxid));
1579+
Assert(TransactionIdIsNormal(relfrozenxid));
15761580

15771581
/* check for values in the future */
1578-
if (TransactionIdPrecedes(lastSaneFrozenXid,classForm->relfrozenxid))
1582+
if (TransactionIdPrecedes(lastSaneFrozenXid,relfrozenxid))
15791583
{
15801584
bogus= true;
15811585
break;
15821586
}
15831587

15841588
/* determine new horizon */
1585-
if (TransactionIdPrecedes(classForm->relfrozenxid,newFrozenXid))
1586-
newFrozenXid=classForm->relfrozenxid;
1589+
if (TransactionIdPrecedes(relfrozenxid,newFrozenXid))
1590+
newFrozenXid=relfrozenxid;
15871591
}
15881592

1589-
if (MultiXactIdIsValid(classForm->relminmxid))
1593+
if (MultiXactIdIsValid(relminmxid))
15901594
{
15911595
/* check for values in the future */
1592-
if (MultiXactIdPrecedes(lastSaneMinMulti,classForm->relminmxid))
1596+
if (MultiXactIdPrecedes(lastSaneMinMulti,relminmxid))
15931597
{
15941598
bogus= true;
15951599
break;
15961600
}
15971601

15981602
/* determine new horizon */
1599-
if (MultiXactIdPrecedes(classForm->relminmxid,newMinMulti))
1600-
newMinMulti=classForm->relminmxid;
1603+
if (MultiXactIdPrecedes(relminmxid,newMinMulti))
1604+
newMinMulti=relminmxid;
16011605
}
16021606
}
16031607

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp