@@ -126,6 +126,9 @@ int max_prepared_xacts = 0;
126
126
*
127
127
* typedef struct GlobalTransactionData *GlobalTransaction appears in
128
128
* twophase.h
129
+ *
130
+ * Note that the max value of GIDSIZE must fit in the uint16 gidlen,
131
+ * specified in TwoPhaseFileHeader.
129
132
*/
130
133
#define GIDSIZE 200
131
134
@@ -851,7 +854,7 @@ TwoPhaseGetDummyProc(TransactionId xid)
851
854
/*
852
855
* Header for a 2PC state file
853
856
*/
854
- #define TWOPHASE_MAGIC 0x57F94532 /* format identifier */
857
+ #define TWOPHASE_MAGIC 0x57F94533 /* format identifier */
855
858
856
859
typedef struct TwoPhaseFileHeader
857
860
{
@@ -866,7 +869,7 @@ typedef struct TwoPhaseFileHeader
866
869
int32 nabortrels ; /* number of delete-on-abort rels */
867
870
int32 ninvalmsgs ; /* number of cache invalidation messages */
868
871
bool initfileinval ; /* does relcache init file need invalidation? */
869
- char gid [ GIDSIZE ]; /* GID for transaction */
872
+ uint16 gidlen ; /* length of the GID - GID follows the header */
870
873
} TwoPhaseFileHeader ;
871
874
872
875
/*
@@ -977,9 +980,10 @@ StartPrepare(GlobalTransaction gxact)
977
980
hdr .nabortrels = smgrGetPendingDeletes (false, & abortrels );
978
981
hdr .ninvalmsgs = xactGetCommittedInvalidationMessages (& invalmsgs ,
979
982
& hdr .initfileinval );
980
- StrNCpy ( hdr .gid , gxact -> gid , GIDSIZE );
983
+ hdr .gidlen = strlen ( gxact -> gid ) + 1 ; /* Include '\0' */
981
984
982
985
save_state_data (& hdr , sizeof (TwoPhaseFileHeader ));
986
+ save_state_data (gxact -> gid , hdr .gidlen );
983
987
984
988
/*
985
989
* Add the additional info about subxacts, deletable files and cache
@@ -1360,6 +1364,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
1360
1364
hdr = (TwoPhaseFileHeader * ) buf ;
1361
1365
Assert (TransactionIdEquals (hdr -> xid , xid ));
1362
1366
bufptr = buf + MAXALIGN (sizeof (TwoPhaseFileHeader ));
1367
+ bufptr += MAXALIGN (hdr -> gidlen );
1363
1368
children = (TransactionId * ) bufptr ;
1364
1369
bufptr += MAXALIGN (hdr -> nsubxacts * sizeof (TransactionId ));
1365
1370
commitrels = (RelFileNode * ) bufptr ;
@@ -1915,6 +1920,7 @@ RecoverPreparedTransactions(void)
1915
1920
TwoPhaseFileHeader * hdr ;
1916
1921
TransactionId * subxids ;
1917
1922
GlobalTransaction gxact ;
1923
+ const char * gid ;
1918
1924
int i ;
1919
1925
1920
1926
xid = (TransactionId ) strtoul (clde -> d_name , NULL , 16 );
@@ -1947,6 +1953,8 @@ RecoverPreparedTransactions(void)
1947
1953
hdr = (TwoPhaseFileHeader * ) buf ;
1948
1954
Assert (TransactionIdEquals (hdr -> xid , xid ));
1949
1955
bufptr = buf + MAXALIGN (sizeof (TwoPhaseFileHeader ));
1956
+ gid = (const char * ) bufptr ;
1957
+ bufptr += MAXALIGN (hdr -> gidlen );
1950
1958
subxids = (TransactionId * ) bufptr ;
1951
1959
bufptr += MAXALIGN (hdr -> nsubxacts * sizeof (TransactionId ));
1952
1960
bufptr += MAXALIGN (hdr -> ncommitrels * sizeof (RelFileNode ));
@@ -1975,7 +1983,7 @@ RecoverPreparedTransactions(void)
1975
1983
/*
1976
1984
* Recreate its GXACT and dummy PGPROC
1977
1985
*/
1978
- gxact = MarkAsPreparing (xid , hdr -> gid ,
1986
+ gxact = MarkAsPreparing (xid , gid ,
1979
1987
hdr -> prepared_at ,
1980
1988
hdr -> owner , hdr -> database );
1981
1989
gxact -> ondisk = true;
0 commit comments