Skip to content

Commit 0f370ad

Browse files
committed
Michael Paquier's suggestions
1 parent 24d1457 commit 0f370ad

File tree

1 file changed

+20
-25
lines changed

1 file changed

+20
-25
lines changed

src/backend/access/transam/twophase.c

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ typedef struct GlobalTransactionData
119119
int pgprocno; /* ID of associated dummy PGPROC */
120120
BackendId dummyBackendId; /* similar to backend id for backends */
121121
TimestampTz prepared_at; /* time of preparation */
122-
XLogRecPtr prepare_lsn; /* XLOG offset of prepare record end */
123-
XLogRecPtr prepare_xlogptr; /* XLOG offset of prepare record start
124-
* or NULL if twophase data moved to file
125-
* after checkpoint.
122+
XLogRecPtr prepare_start_lsn; /* XLOG offset of prepare record start
123+
* or InvalidXLogRecPtr if twophase data
124+
* moved to file after checkpoint.
126125
*/
126+
XLogRecPtr prepare_end_lsn; /* XLOG offset of prepare record end */
127127
Oid owner; /* ID of user that executed the xact */
128128
BackendId locking_backend; /* backend currently working on the xact */
129129
bool valid; /* TRUE if PGPROC entry is in proc array */
@@ -405,9 +405,9 @@ MarkAsPreparing(TransactionId xid, const char *gid,
405405
pgxact->nxids = 0;
406406

407407
gxact->prepared_at = prepared_at;
408-
/* initialize LSN to 0 (start of WAL) */
409-
gxact->prepare_lsn = 0;
410-
gxact->prepare_xlogptr = 0;
408+
/* initialize LSN to InvalidXLogRecPtr */
409+
gxact->prepare_start_lsn = InvalidXLogRecPtr;
410+
gxact->prepare_end_lsn = InvalidXLogRecPtr;
411411
gxact->owner = owner;
412412
gxact->locking_backend = MyBackendId;
413413
gxact->valid = false;
@@ -1035,13 +1035,13 @@ EndPrepare(GlobalTransaction gxact)
10351035
XLogBeginInsert();
10361036
for (record = records.head; record != NULL; record = record->next)
10371037
XLogRegisterData(record->data, record->len);
1038-
gxact->prepare_lsn = XLogInsert(RM_XACT_ID, XLOG_XACT_PREPARE);
1039-
XLogFlush(gxact->prepare_lsn);
1038+
gxact->prepare_end_lsn = XLogInsert(RM_XACT_ID, XLOG_XACT_PREPARE);
1039+
XLogFlush(gxact->prepare_end_lsn);
10401040

10411041
/* If we crash now, we have prepared: WAL replay will fix things */
10421042

10431043
/* Store record's start location to read that later on Commit */
1044-
gxact->prepare_xlogptr = ProcLastRecPtr;
1044+
gxact->prepare_start_lsn = ProcLastRecPtr;
10451045

10461046
/*
10471047
* Mark the prepared transaction as valid. As soon as xact.c marks
@@ -1079,7 +1079,7 @@ EndPrepare(GlobalTransaction gxact)
10791079
* Note that at this stage we have marked the prepare, but still show as
10801080
* running in the procarray (twice!) and continue to hold locks.
10811081
*/
1082-
SyncRepWaitForLSN(gxact->prepare_lsn);
1082+
SyncRepWaitForLSN(gxact->prepare_end_lsn);
10831083

10841084
records.tail = records.head = NULL;
10851085
records.num_chunks = 0;
@@ -1301,12 +1301,12 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
13011301
/*
13021302
* Read and validate 2PC state data.
13031303
* State data can be stored in xlog or in files after xlog checkpoint.
1304-
* While checkpointing we set gxact->prepare_lsn to NULL to signalize
1304+
* While checkpointing we set gxact->prepare_start_lsn to NULL to signalize
13051305
* that 2PC data is moved to files.
13061306
*/
1307-
if (gxact->prepare_lsn)
1307+
if (gxact->prepare_start_lsn)
13081308
{
1309-
XlogReadTwoPhaseData(gxact->prepare_xlogptr, &buf, NULL);
1309+
XlogReadTwoPhaseData(gxact->prepare_start_lsn, &buf, NULL);
13101310
}
13111311
else
13121312
{
@@ -1556,8 +1556,6 @@ CheckPointTwoPhase(XLogRecPtr redo_horizon)
15561556
int len;
15571557
char *buf;
15581558

1559-
fprintf(stderr, "=== Checkpoint: redo_horizon=%lX\n", redo_horizon);
1560-
15611559
if (max_prepared_xacts <= 0)
15621560
return; /* nothing to do */
15631561

@@ -1577,10 +1575,11 @@ CheckPointTwoPhase(XLogRecPtr redo_horizon)
15771575
GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
15781576
PGXACT *pgxact = &ProcGlobal->allPgXact[gxact->pgprocno];
15791577

1580-
if (gxact->valid && gxact->prepare_lsn && gxact->prepare_lsn <= redo_horizon){
1581-
XlogReadTwoPhaseData(gxact->prepare_xlogptr, &buf, &len);
1578+
if (gxact->valid && gxact->prepare_start_lsn != InvalidXLogRecPtr &&
1579+
gxact->prepare_end_lsn <= redo_horizon){
1580+
XlogReadTwoPhaseData(gxact->prepare_start_lsn, &buf, &len);
15821581
RecreateTwoPhaseFile(pgxact->xid, buf, len);
1583-
gxact->prepare_lsn = (XLogRecPtr) NULL;
1582+
gxact->prepare_start_lsn = InvalidXLogRecPtr;
15841583
pfree(buf);
15851584
}
15861585
}
@@ -1916,12 +1915,8 @@ RecoverPreparedTransactions(void)
19161915
/*
19171916
* Recreate its GXACT and dummy PGPROC
19181917
*
1919-
* Note: since we don't have the PREPARE record's WAL location at
1920-
* hand, we leave prepare_lsn zeroes. This means the GXACT will
1921-
* be fsync'd on every future checkpoint. We assume this
1922-
* situation is infrequent enough that the performance cost is
1923-
* negligible (especially since we know the state file has already
1924-
* been fsynced).
1918+
* MarkAsPreparing sets prepare_start_lsn to InvalidXLogRecPtr
1919+
* so next checkpoint will skip that transaction.
19251920
*/
19261921
gxact = MarkAsPreparing(xid, hdr->gid,
19271922
hdr->prepared_at,

0 commit comments

Comments
 (0)