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:
parent
2cdf131c46
commit
5a1dfde833
@ -942,8 +942,46 @@ TwoPhaseGetDummyProc(TransactionId xid, bool lock_held)
|
|||||||
/* State file support */
|
/* 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:
|
* 2PC state file format:
|
||||||
@ -1882,13 +1920,15 @@ restoreTwoPhaseData(void)
|
|||||||
cldir = AllocateDir(TWOPHASE_DIR);
|
cldir = AllocateDir(TWOPHASE_DIR);
|
||||||
while ((clde = ReadDir(cldir, TWOPHASE_DIR)) != NULL)
|
while ((clde = ReadDir(cldir, TWOPHASE_DIR)) != NULL)
|
||||||
{
|
{
|
||||||
if (strlen(clde->d_name) == 8 &&
|
if (strlen(clde->d_name) == 16 &&
|
||||||
strspn(clde->d_name, "0123456789ABCDEF") == 8)
|
strspn(clde->d_name, "0123456789ABCDEF") == 16)
|
||||||
{
|
{
|
||||||
TransactionId xid;
|
TransactionId xid;
|
||||||
|
FullTransactionId fxid;
|
||||||
char *buf;
|
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,
|
buf = ProcessTwoPhaseBuffer(xid, InvalidXLogRecPtr,
|
||||||
true, false, false);
|
true, false, false);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user