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
This commit is contained in:
Alexander Korotkov 2023-11-29 01:43:13 +02:00
parent 2cdf131c46
commit 5a1dfde833
1 changed files with 45 additions and 5 deletions

View File

@ -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);