@@ -942,8 +942,46 @@ TwoPhaseGetDummyProc(TransactionId xid, bool lock_held)
942
942
/* State file support */
943
943
/************************************************************************/
944
944
945
- #define TwoPhaseFilePath (path , xid ) \
946
- snprintf(path, MAXPGPATH, TWOPHASE_DIR "/%08X", xid)
945
+ /*
946
+ * Compute the FullTransactionId for the given TransactionId.
947
+ *
948
+ * The wrap logic is safe here because the span of active xids cannot exceed one
949
+ * epoch at any given time.
950
+ */
951
+ static inline FullTransactionId
952
+ AdjustToFullTransactionId (TransactionId xid )
953
+ {
954
+ FullTransactionId nextFullXid ;
955
+ TransactionId nextXid ;
956
+ uint32 epoch ;
957
+
958
+ Assert (TransactionIdIsValid (xid ));
959
+
960
+ LWLockAcquire (XidGenLock , LW_SHARED );
961
+ nextFullXid = ShmemVariableCache -> nextXid ;
962
+ LWLockRelease (XidGenLock );
963
+
964
+ nextXid = XidFromFullTransactionId (nextFullXid );
965
+ epoch = EpochFromFullTransactionId (nextFullXid );
966
+ if (unlikely (xid > nextXid ))
967
+ {
968
+ /* Wraparound occured, must be from a prev epoch. */
969
+ Assert (epoch > 0 );
970
+ epoch -- ;
971
+ }
972
+
973
+ return FullTransactionIdFromEpochAndXid (epoch , xid );
974
+ }
975
+
976
+ static inline int
977
+ TwoPhaseFilePath (char * path , TransactionId xid )
978
+ {
979
+ FullTransactionId fxid = AdjustToFullTransactionId (xid );
980
+
981
+ return snprintf (path , MAXPGPATH , TWOPHASE_DIR "/%08X%08X" ,
982
+ EpochFromFullTransactionId (fxid ),
983
+ XidFromFullTransactionId (fxid ));
984
+ }
947
985
948
986
/*
949
987
* 2PC state file format:
@@ -1882,13 +1920,15 @@ restoreTwoPhaseData(void)
1882
1920
cldir = AllocateDir (TWOPHASE_DIR );
1883
1921
while ((clde = ReadDir (cldir , TWOPHASE_DIR )) != NULL )
1884
1922
{
1885
- if (strlen (clde -> d_name ) == 8 &&
1886
- strspn (clde -> d_name , "0123456789ABCDEF" ) == 8 )
1923
+ if (strlen (clde -> d_name ) == 16 &&
1924
+ strspn (clde -> d_name , "0123456789ABCDEF" ) == 16 )
1887
1925
{
1888
1926
TransactionId xid ;
1927
+ FullTransactionId fxid ;
1889
1928
char * buf ;
1890
1929
1891
- xid = (TransactionId ) strtoul (clde -> d_name , NULL , 16 );
1930
+ fxid = FullTransactionIdFromU64 (strtou64 (clde -> d_name , NULL , 16 ));
1931
+ xid = XidFromFullTransactionId (fxid );
1892
1932
1893
1933
buf = ProcessTwoPhaseBuffer (xid , InvalidXLogRecPtr ,
1894
1934
true, false, false);
0 commit comments