@@ -126,6 +126,9 @@ int max_prepared_xacts = 0;
126126 *
127127 * typedef struct GlobalTransactionData *GlobalTransaction appears in
128128 * twophase.h
129+ *
130+ * Note that the max value of GIDSIZE must fit in the uint16 gidlen,
131+ * specified in TwoPhaseFileHeader.
129132 */
130133#define GIDSIZE 200
131134
@@ -851,7 +854,7 @@ TwoPhaseGetDummyProc(TransactionId xid)
851854/*
852855 * Header for a 2PC state file
853856 */
854- #define TWOPHASE_MAGIC 0x57F94532 /* format identifier */
857+ #define TWOPHASE_MAGIC 0x57F94533 /* format identifier */
855858
856859typedef struct TwoPhaseFileHeader
857860{
@@ -866,7 +869,7 @@ typedef struct TwoPhaseFileHeader
866869 int32 nabortrels ; /* number of delete-on-abort rels */
867870 int32 ninvalmsgs ; /* number of cache invalidation messages */
868871 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 */
870873} TwoPhaseFileHeader ;
871874
872875/*
@@ -977,9 +980,10 @@ StartPrepare(GlobalTransaction gxact)
977980 hdr .nabortrels = smgrGetPendingDeletes (false, & abortrels );
978981 hdr .ninvalmsgs = xactGetCommittedInvalidationMessages (& invalmsgs ,
979982 & hdr .initfileinval );
980- StrNCpy ( hdr .gid , gxact -> gid , GIDSIZE );
983+ hdr .gidlen = strlen ( gxact -> gid ) + 1 ; /* Include '\0' */
981984
982985 save_state_data (& hdr , sizeof (TwoPhaseFileHeader ));
986+ save_state_data (gxact -> gid , hdr .gidlen );
983987
984988 /*
985989 * Add the additional info about subxacts, deletable files and cache
@@ -1360,6 +1364,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
13601364 hdr = (TwoPhaseFileHeader * ) buf ;
13611365 Assert (TransactionIdEquals (hdr -> xid , xid ));
13621366 bufptr = buf + MAXALIGN (sizeof (TwoPhaseFileHeader ));
1367+ bufptr += MAXALIGN (hdr -> gidlen );
13631368 children = (TransactionId * ) bufptr ;
13641369 bufptr += MAXALIGN (hdr -> nsubxacts * sizeof (TransactionId ));
13651370 commitrels = (RelFileNode * ) bufptr ;
@@ -1915,6 +1920,7 @@ RecoverPreparedTransactions(void)
19151920 TwoPhaseFileHeader * hdr ;
19161921 TransactionId * subxids ;
19171922 GlobalTransaction gxact ;
1923+ const char * gid ;
19181924 int i ;
19191925
19201926 xid = (TransactionId ) strtoul (clde -> d_name , NULL , 16 );
@@ -1947,6 +1953,8 @@ RecoverPreparedTransactions(void)
19471953 hdr = (TwoPhaseFileHeader * ) buf ;
19481954 Assert (TransactionIdEquals (hdr -> xid , xid ));
19491955 bufptr = buf + MAXALIGN (sizeof (TwoPhaseFileHeader ));
1956+ gid = (const char * ) bufptr ;
1957+ bufptr += MAXALIGN (hdr -> gidlen );
19501958 subxids = (TransactionId * ) bufptr ;
19511959 bufptr += MAXALIGN (hdr -> nsubxacts * sizeof (TransactionId ));
19521960 bufptr += MAXALIGN (hdr -> ncommitrels * sizeof (RelFileNode ));
@@ -1975,7 +1983,7 @@ RecoverPreparedTransactions(void)
19751983 /*
19761984 * Recreate its GXACT and dummy PGPROC
19771985 */
1978- gxact = MarkAsPreparing (xid , hdr -> gid ,
1986+ gxact = MarkAsPreparing (xid , gid ,
19791987 hdr -> prepared_at ,
19801988 hdr -> owner , hdr -> database );
19811989 gxact -> ondisk = true;
0 commit comments