aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam
diff options
context:
space:
mode:
authorAlexander Korotkov <akorotkov@postgresql.org>2023-11-29 01:43:13 +0200
committerAlexander Korotkov <akorotkov@postgresql.org>2023-11-29 01:43:36 +0200
commit5a1dfde8334b25e19bf4b3aa75274c547a3aa30f (patch)
treeb638f9c86634334b4128337408d7395bfe4bd93d /src/backend/access/transam
parent2cdf131c46e631addfc386f6106e52a1b8cc3a70 (diff)
downloadpostgresql-5a1dfde8334b25e19bf4b3aa75274c547a3aa30f.tar.gz
postgresql-5a1dfde8334b25e19bf4b3aa75274c547a3aa30f.zip
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, Aleksander Alekseev, Alexander Korotkov, Teodor Sigaev Author: Nikita Glukhov, Pavel Borisov, Yura Sokolov Reviewed-by: Jacob Champion, Heikki Linnakangas, Alexander Korotkov Reviewed-by: Japin Li, Pavel Borisov, Tom Lane, Peter Eisentraut, Andres Freund Reviewed-by: Andrey Borodin, Dilip Kumar, Aleksander Alekseev Discussion: https://postgr.es/m/CACG%3DezZe1NQSCnfHOr78AtAZxJZeCvxrts0ygrxYwe%3DpyyjVWA%40mail.gmail.com Discussion: https://postgr.es/m/CAJ7c6TPDOYBYrnCAeyndkBktO0WG2xSdYduTF0nxq%2BvfkmTF5Q%40mail.gmail.com
Diffstat (limited to 'src/backend/access/transam')
-rw-r--r--src/backend/access/transam/twophase.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index c6af8cfd7e2..a91ef0deeaf 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -942,8 +942,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:
@@ -1882,13 +1920,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);