v3-0002-Partition-2PCs-first-during-wait.patch
application/octet-stream
Filename: v3-0002-Partition-2PCs-first-during-wait.patch
Type: application/octet-stream
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v3-0002
Subject: Partition 2PCs first during wait
| File | + | − |
|---|---|---|
| src/backend/access/transam/twophase.c | 4 | 3 |
| src/backend/storage/lmgr/lmgr.c | 28 | 4 |
From a4db2c29cb07e0129af2734a31299bae9bdfe680 Mon Sep 17 00:00:00 2001
From: Andrey Borodin <amborodin@acm.org>
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)