]> granicus.if.org Git - postgresql/commitdiff
Reduce size of two phase file header
authorSimon Riggs <simon@2ndQuadrant.com>
Thu, 10 Mar 2016 12:51:46 +0000 (12:51 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Thu, 10 Mar 2016 12:51:46 +0000 (12:51 +0000)
Previously 2PC header was fixed at 200 bytes, which in most cases wasted
WAL space for a workload using 2PC heavily.

Pavan Deolasee, reviewed by Petr Jelinek

src/backend/access/transam/twophase.c

index 8a22836406afd02c61ba190841b60e6b7e9758f3..c4fd9eff87033ad7b95757c69744af5a44ca82e9 100644 (file)
@@ -126,6 +126,9 @@ int                 max_prepared_xacts = 0;
  *
  * typedef struct GlobalTransactionData *GlobalTransaction appears in
  * twophase.h
+ *
+ * Note that the max value of GIDSIZE must fit in the uint16 gidlen,
+ * specified in TwoPhaseFileHeader.
  */
 #define GIDSIZE 200
 
@@ -851,7 +854,7 @@ TwoPhaseGetDummyProc(TransactionId xid)
 /*
  * Header for a 2PC state file
  */
-#define TWOPHASE_MAGIC 0x57F94532              /* format identifier */
+#define TWOPHASE_MAGIC 0x57F94533              /* format identifier */
 
 typedef struct TwoPhaseFileHeader
 {
@@ -866,7 +869,7 @@ typedef struct TwoPhaseFileHeader
        int32           nabortrels;             /* number of delete-on-abort rels */
        int32           ninvalmsgs;             /* number of cache invalidation messages */
        bool            initfileinval;  /* does relcache init file need invalidation? */
-       char            gid[GIDSIZE];   /* GID for transaction */
+       uint16          gidlen;                 /* length of the GID - GID follows the header */
 } TwoPhaseFileHeader;
 
 /*
@@ -977,9 +980,10 @@ StartPrepare(GlobalTransaction gxact)
        hdr.nabortrels = smgrGetPendingDeletes(false, &abortrels);
        hdr.ninvalmsgs = xactGetCommittedInvalidationMessages(&invalmsgs,
                                                                                                                  &hdr.initfileinval);
-       StrNCpy(hdr.gid, gxact->gid, GIDSIZE);
+       hdr.gidlen = strlen(gxact->gid) + 1; /* Include '\0' */
 
        save_state_data(&hdr, sizeof(TwoPhaseFileHeader));
+       save_state_data(gxact->gid, hdr.gidlen);
 
        /*
         * Add the additional info about subxacts, deletable files and cache
@@ -1360,6 +1364,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
        hdr = (TwoPhaseFileHeader *) buf;
        Assert(TransactionIdEquals(hdr->xid, xid));
        bufptr = buf + MAXALIGN(sizeof(TwoPhaseFileHeader));
+       bufptr += MAXALIGN(hdr->gidlen);
        children = (TransactionId *) bufptr;
        bufptr += MAXALIGN(hdr->nsubxacts * sizeof(TransactionId));
        commitrels = (RelFileNode *) bufptr;
@@ -1915,6 +1920,7 @@ RecoverPreparedTransactions(void)
                        TwoPhaseFileHeader *hdr;
                        TransactionId *subxids;
                        GlobalTransaction gxact;
+                       const char      *gid;
                        int                     i;
 
                        xid = (TransactionId) strtoul(clde->d_name, NULL, 16);
@@ -1947,6 +1953,8 @@ RecoverPreparedTransactions(void)
                        hdr = (TwoPhaseFileHeader *) buf;
                        Assert(TransactionIdEquals(hdr->xid, xid));
                        bufptr = buf + MAXALIGN(sizeof(TwoPhaseFileHeader));
+                       gid = (const char *) bufptr;
+                       bufptr += MAXALIGN(hdr->gidlen);
                        subxids = (TransactionId *) bufptr;
                        bufptr += MAXALIGN(hdr->nsubxacts * sizeof(TransactionId));
                        bufptr += MAXALIGN(hdr->ncommitrels * sizeof(RelFileNode));
@@ -1975,7 +1983,7 @@ RecoverPreparedTransactions(void)
                        /*
                         * Recreate its GXACT and dummy PGPROC
                         */
-                       gxact = MarkAsPreparing(xid, hdr->gid,
+                       gxact = MarkAsPreparing(xid, gid,
                                                                        hdr->prepared_at,
                                                                        hdr->owner, hdr->database);
                        gxact->ondisk = true;