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

Commit3c27944

Browse files
committed
Make XactLockTableWait work for transactions that are not yet self-locked
XactLockTableWait assumed that its xid argument has already added itselfto the lock table. That assumption led to another assumption that iflocking the xid has succeeded but the xid is reported as still inprogress, then the input xid must have been a subtransaction.These assumptions hold true for the original uses of this code inlocking related to on-disk tuples, but they break down in logicalreplication slot snapshot building -- in particular, when a standbysnapshot logged contains an xid that's already in ProcArray but not yetin the lock table. This leads to assertion failures that can bereproduced all the way back to 9.4, when logical decoding wasintroduced.To fix, change SubTransGetParent to SubTransGetTopmostTransaction whichhas a slightly different API: it returns the argument Xid if there is noparent, and it goes all the way to the top instead of moving up thelevels one by one. Also, to avoid busy-waiting, add a 1ms sleep to givethe other process time to register itself in the lock table.For consistency, change ConditionalXactLockTableWait the same way.Author: Petr JelínekDiscussion:https://postgr.es/m/1B3E32D8-FCF4-40B4-AEF9-5C0E3AC57969@postgrespro.ruReported-by: Konstantin KnizhnikDiagnosed-by: Stas Kelvich, Petr JelínekReviewed-by: Andres Freund, Robert Haas
1 parent6fcde24 commit3c27944

File tree

1 file changed

+28
-2
lines changed
  • src/backend/storage/lmgr

1 file changed

+28
-2
lines changed

‎src/backend/storage/lmgr/lmgr.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
557557
LOCKTAGtag;
558558
XactLockTableWaitInfoinfo;
559559
ErrorContextCallbackcallback;
560+
boolfirst= true;
560561

561562
/*
562563
* If an operation is specified, set up our verbose error context
@@ -590,7 +591,26 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid,
590591

591592
if (!TransactionIdIsInProgress(xid))
592593
break;
593-
xid=SubTransGetParent(xid);
594+
595+
/*
596+
* If the Xid belonged to a subtransaction, then the lock would have
597+
* gone away as soon as it was finished; for correct tuple visibility,
598+
* the right action is to wait on its parent transaction to go away.
599+
* But instead of going levels up one by one, we can just wait for the
600+
* topmost transaction to finish with the same end result, which also
601+
* incurs less locktable traffic.
602+
*
603+
* Some uses of this function don't involve tuple visibility -- such
604+
* as when building snapshots for logical decoding. It is possible to
605+
* see a transaction in ProcArray before it registers itself in the
606+
* locktable. The topmost transaction in that case is the same xid,
607+
* so we try again after a short sleep. (Don't sleep the first time
608+
* through, to avoid slowing down the normal case.)
609+
*/
610+
if (!first)
611+
pg_usleep(1000L);
612+
first= false;
613+
xid=SubTransGetTopmostTransaction(xid);
594614
}
595615

596616
if (oper!=XLTW_None)
@@ -607,6 +627,7 @@ bool
607627
ConditionalXactLockTableWait(TransactionIdxid)
608628
{
609629
LOCKTAGtag;
630+
boolfirst= true;
610631

611632
for (;;)
612633
{
@@ -622,7 +643,12 @@ ConditionalXactLockTableWait(TransactionId xid)
622643

623644
if (!TransactionIdIsInProgress(xid))
624645
break;
625-
xid=SubTransGetParent(xid);
646+
647+
/* See XactLockTableWait about this case */
648+
if (!first)
649+
pg_usleep(1000L);
650+
first= false;
651+
xid=SubTransGetTopmostTransaction(xid);
626652
}
627653

628654
return true;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp