From a4db2c29cb07e0129af2734a31299bae9bdfe680 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Wed, 21 Jul 2021 00:24:13 +0500 Subject: [PATCH v3 2/2] Partition 2PCs first during wait --- src/backend/access/transam/twophase.c | 7 +++--- src/backend/storage/lmgr/lmgr.c | 32 +++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index dba302d322..836c9339af 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -852,7 +852,7 @@ TwoPhaseGetGXact(TransactionId xid, bool lock_held) /* * TwoPhaseGetXidByVXid - * Try to lookup for vxid among prepared xacts + * Try to lookup earliest xid for vxid among prepared xacts */ TransactionId TwoPhaseGetXidByVXid(VirtualTransactionId vxid) @@ -871,8 +871,9 @@ TwoPhaseGetXidByVXid(VirtualTransactionId vxid) if (proc->backendId == vxid.backendId && proc->lxid == vxid.localTransactionId) { - result = gxact->xid; - break; + if (result == InvalidTransactionId || + TransactionIdPrecedes(gxact->xid, result)) + result = gxact->xid; } } diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c index cdf2266d6d..d03ce465cc 100644 --- a/src/backend/storage/lmgr/lmgr.c +++ b/src/backend/storage/lmgr/lmgr.c @@ -912,20 +912,44 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress) foreach(lc, holders) { VirtualTransactionId *lockholders = lfirst(lc); + int nholders = 0; + int i = 0, j; - while (VirtualTransactionIdIsValid(*lockholders)) + while (VirtualTransactionIdIsValid(lockholders[nholders])) + nholders++; + j = nholders - 1; + + /* partition 2PC first */ + while (nholders > 0) + { + while (i < nholders && VirtualTransactionIdIsPreparedXact(lockholders[i])) + i++; + while (j >= 0 && !VirtualTransactionIdIsPreparedXact(lockholders[j])) + j--; + if (i < j) + { + VirtualTransactionId tmp = lockholders[i]; + lockholders[i] = lockholders[j]; + lockholders[j] = tmp; + i++; + j++; + } + if (i >= j) + break; + } + + for (i = 0; i < nholders; i++) { /* If requested, publish who we're going to wait for. */ if (progress) { - PGPROC *holder = BackendIdGetProc(lockholders->backendId); + PGPROC *holder = BackendIdGetProc(lockholders[i].backendId); if (holder) pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID, holder->pid); } - VirtualXactLock(*lockholders, true); - lockholders++; + VirtualXactLock(lockholders[i], true); if (progress) pgstat_progress_update_param(PROGRESS_WAITFOR_DONE, ++done); -- 2.24.3 (Apple Git-128)