1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-22 23:02:54 +03:00

Reduce size of two phase file header

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
This commit is contained in:
Simon Riggs 2016-03-10 12:51:46 +00:00
parent fcb4bfddb6
commit e0694cf9c7

View File

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