v58-0003-Make-use-FullTransactionId-in-2PC-filenames.patch
application/octet-stream
Filename: v58-0003-Make-use-FullTransactionId-in-2PC-filenames.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v58-0003
Subject: Make use FullTransactionId in 2PC filenames
| File | + | − |
|---|---|---|
| src/backend/access/transam/twophase.c | 45 | 5 |
From 01cb7d0bf5a761d47cf89cc60358458e2e77fc7f Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Mon, 20 Mar 2023 18:23:55 +0300
Subject: [PATCH v58 3/3] Make use FullTransactionId in 2PC filenames
Switch from using TransactionId to FullTransactionId in naming of 2PC files.
Transaction state file in the pg_twophase directory now have extra 8 bytes in
the name to address an epoch of a given xid.
Author: Maxim Orlov
Discussion: https://postgr.es/m/CAJ7c6TPDOYBYrnCAeyndkBktO0WG2xSdYduTF0nxq%2BvfkmTF5Q%40mail.gmail.com
---
src/backend/access/transam/twophase.c | 50 ++++++++++++++++++++++++---
1 file changed, 45 insertions(+), 5 deletions(-)
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 068e59bec0..e103ffb6d3 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -941,8 +941,46 @@ TwoPhaseGetDummyProc(TransactionId xid, bool lock_held)
/* State file support */
/************************************************************************/
-#define TwoPhaseFilePath(path, xid) \
- snprintf(path, MAXPGPATH, TWOPHASE_DIR "/%08X", xid)
+/*
+ * Compute the FullTransactionId for the given TransactionId.
+ *
+ * The wrap logic is safe here because the span of active xids cannot exceed one
+ * epoch at any given time.
+ */
+static inline FullTransactionId
+AdjustToFullTransactionId(TransactionId xid)
+{
+ FullTransactionId nextFullXid;
+ TransactionId nextXid;
+ uint32 epoch;
+
+ Assert(TransactionIdIsValid(xid));
+
+ LWLockAcquire(XidGenLock, LW_SHARED);
+ nextFullXid = ShmemVariableCache->nextXid;
+ LWLockRelease(XidGenLock);
+
+ nextXid = XidFromFullTransactionId(nextFullXid);
+ epoch = EpochFromFullTransactionId(nextFullXid);
+ if (unlikely(xid > nextXid))
+ {
+ /* Wraparound occured, must be from a prev epoch. */
+ Assert(epoch > 0);
+ epoch--;
+ }
+
+ return FullTransactionIdFromEpochAndXid(epoch, xid);
+}
+
+static inline int
+TwoPhaseFilePath(char *path, TransactionId xid)
+{
+ FullTransactionId fxid = AdjustToFullTransactionId(xid);
+
+ return snprintf(path, MAXPGPATH, TWOPHASE_DIR "/%08X%08X",
+ EpochFromFullTransactionId(fxid),
+ XidFromFullTransactionId(fxid));
+}
/*
* 2PC state file format:
@@ -1881,13 +1919,15 @@ restoreTwoPhaseData(void)
cldir = AllocateDir(TWOPHASE_DIR);
while ((clde = ReadDir(cldir, TWOPHASE_DIR)) != NULL)
{
- if (strlen(clde->d_name) == 8 &&
- strspn(clde->d_name, "0123456789ABCDEF") == 8)
+ if (strlen(clde->d_name) == 16 &&
+ strspn(clde->d_name, "0123456789ABCDEF") == 16)
{
TransactionId xid;
+ FullTransactionId fxid;
char *buf;
- xid = (TransactionId) strtoul(clde->d_name, NULL, 16);
+ fxid = FullTransactionIdFromU64(strtou64(clde->d_name, NULL, 16));
+ xid = XidFromFullTransactionId(fxid);
buf = ProcessTwoPhaseBuffer(xid, InvalidXLogRecPtr,
true, false, false);
--
2.41.0