Skip to content

Commit 71db645

Browse files
author
Amit Kapila
committed
Replace XLOG_INCLUDE_XID flag with a more localized flag.
Commit 0bead9a introduced XLOG_INCLUDE_XID flag to indicate that the WAL record contains subXID-to-topXID association. It uses that flag later to mark in CurrentTransactionState that top-xid is logged so that we should not try to log it again with the next WAL record in the current subtransaction. However, we can use a localized variable to pass that information. In passing, change the related function and variable names to make them consistent with what the code is actually doing. Author: Dilip Kumar Reviewed-by: Alvaro Herrera, Amit Kapila Discussion: https://postgr.es/m/E1mSoYz-0007Fh-D9@gemulon.postgresql.org
1 parent 43a134f commit 71db645

File tree

5 files changed

+82
-68
lines changed

5 files changed

+82
-68
lines changed

src/backend/access/transam/xact.c

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ typedef struct TransactionStateData
205205
bool didLogXid; /* has xid been included in WAL record? */
206206
int parallelModeLevel; /* Enter/ExitParallelMode counter */
207207
bool chain; /* start a new block after this one */
208-
bool assigned; /* assigned to top-level XID */
208+
bool topXidLogged; /* for a subxact: is top-level XID logged? */
209209
struct TransactionStateData *parent; /* back link to parent */
210210
} TransactionStateData;
211211

@@ -238,7 +238,7 @@ typedef struct SerializedTransactionState
238238
static TransactionStateData TopTransactionStateData = {
239239
.state = TRANS_DEFAULT,
240240
.blockState = TBLOCK_DEFAULT,
241-
.assigned = false,
241+
.topXidLogged = false,
242242
};
243243

244244
/*
@@ -529,6 +529,56 @@ MarkCurrentTransactionIdLoggedIfAny(void)
529529
CurrentTransactionState->didLogXid = true;
530530
}
531531

532+
/*
533+
* IsSubxactTopXidLogPending
534+
*
535+
* This is used to decide whether we need to WAL log the top-level XID for
536+
* operation in a subtransaction. We require that for logical decoding, see
537+
* LogicalDecodingProcessRecord.
538+
*
539+
* This returns true if wal_level >= logical and we are inside a valid
540+
* subtransaction, for which the assignment was not yet written to any WAL
541+
* record.
542+
*/
543+
bool
544+
IsSubxactTopXidLogPending(void)
545+
{
546+
/* check whether it is already logged */
547+
if (CurrentTransactionState->topXidLogged)
548+
return false;
549+
550+
/* wal_level has to be logical */
551+
if (!XLogLogicalInfoActive())
552+
return false;
553+
554+
/* we need to be in a transaction state */
555+
if (!IsTransactionState())
556+
return false;
557+
558+
/* it has to be a subtransaction */
559+
if (!IsSubTransaction())
560+
return false;
561+
562+
/* the subtransaction has to have a XID assigned */
563+
if (!TransactionIdIsValid(GetCurrentTransactionIdIfAny()))
564+
return false;
565+
566+
return true;
567+
}
568+
569+
/*
570+
* MarkSubxactTopXidLogged
571+
*
572+
* Remember that the top transaction id for the current subtransaction is WAL
573+
* logged now.
574+
*/
575+
void
576+
MarkSubxactTopXidLogged(void)
577+
{
578+
Assert(IsSubxactTopXidLogPending());
579+
580+
CurrentTransactionState->topXidLogged = true;
581+
}
532582

533583
/*
534584
* GetStableLatestTransactionId
@@ -5174,7 +5224,7 @@ PushTransaction(void)
51745224
GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
51755225
s->prevXactReadOnly = XactReadOnly;
51765226
s->parallelModeLevel = 0;
5177-
s->assigned = false;
5227+
s->topXidLogged = false;
51785228

51795229
CurrentTransactionState = s;
51805230

@@ -6106,50 +6156,3 @@ xact_redo(XLogReaderState *record)
61066156
else
61076157
elog(PANIC, "xact_redo: unknown op code %u", info);
61086158
}
6109-
6110-
/*
6111-
* IsSubTransactionAssignmentPending
6112-
*
6113-
* This is used to decide whether we need to WAL log the top-level XID for
6114-
* operation in a subtransaction. We require that for logical decoding, see
6115-
* LogicalDecodingProcessRecord.
6116-
*
6117-
* This returns true if wal_level >= logical and we are inside a valid
6118-
* subtransaction, for which the assignment was not yet written to any WAL
6119-
* record.
6120-
*/
6121-
bool
6122-
IsSubTransactionAssignmentPending(void)
6123-
{
6124-
/* wal_level has to be logical */
6125-
if (!XLogLogicalInfoActive())
6126-
return false;
6127-
6128-
/* we need to be in a transaction state */
6129-
if (!IsTransactionState())
6130-
return false;
6131-
6132-
/* it has to be a subtransaction */
6133-
if (!IsSubTransaction())
6134-
return false;
6135-
6136-
/* the subtransaction has to have a XID assigned */
6137-
if (!TransactionIdIsValid(GetCurrentTransactionIdIfAny()))
6138-
return false;
6139-
6140-
/* and it should not be already 'assigned' */
6141-
return !CurrentTransactionState->assigned;
6142-
}
6143-
6144-
/*
6145-
* MarkSubTransactionAssigned
6146-
*
6147-
* Mark the subtransaction assignment as completed.
6148-
*/
6149-
void
6150-
MarkSubTransactionAssigned(void)
6151-
{
6152-
Assert(IsSubTransactionAssignmentPending());
6153-
6154-
CurrentTransactionState->assigned = true;
6155-
}

src/backend/access/transam/xlog.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,9 @@ static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt);
999999
* 'flags' gives more in-depth control on the record being inserted. See
10001000
* XLogSetRecordFlags() for details.
10011001
*
1002+
* 'topxid_included' tells whether the top-transaction id is logged along with
1003+
* current subtransaction. See XLogRecordAssemble().
1004+
*
10021005
* The first XLogRecData in the chain must be for the record header, and its
10031006
* data must be MAXALIGNed. XLogInsertRecord fills in the xl_prev and
10041007
* xl_crc fields in the header, the rest of the header must already be filled
@@ -1014,7 +1017,8 @@ XLogRecPtr
10141017
XLogInsertRecord(XLogRecData *rdata,
10151018
XLogRecPtr fpw_lsn,
10161019
uint8 flags,
1017-
int num_fpi)
1020+
int num_fpi,
1021+
bool topxid_included)
10181022
{
10191023
XLogCtlInsert *Insert = &XLogCtl->Insert;
10201024
pg_crc32c rdata_crc;
@@ -1169,6 +1173,13 @@ XLogInsertRecord(XLogRecData *rdata,
11691173

11701174
END_CRIT_SECTION();
11711175

1176+
/*
1177+
* Mark top transaction id is logged (if needed) so that we should not try
1178+
* to log it again with the next WAL record in the current subtransaction.
1179+
*/
1180+
if (topxid_included)
1181+
MarkSubxactTopXidLogged();
1182+
11721183
/*
11731184
* Update shared LogwrtRqst.Write, if we crossed page boundary.
11741185
*/

src/backend/access/transam/xloginsert.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ static MemoryContext xloginsert_cxt;
123123

124124
static XLogRecData *XLogRecordAssemble(RmgrId rmid, uint8 info,
125125
XLogRecPtr RedoRecPtr, bool doPageWrites,
126-
XLogRecPtr *fpw_lsn, int *num_fpi);
126+
XLogRecPtr *fpw_lsn, int *num_fpi,
127+
bool *topxid_included);
127128
static bool XLogCompressBackupBlock(char *page, uint16 hole_offset,
128129
uint16 hole_length, char *dest, uint16 *dlen);
129130

@@ -209,10 +210,6 @@ XLogResetInsertion(void)
209210
{
210211
int i;
211212

212-
/* reset the subxact assignment flag (if needed) */
213-
if (curinsert_flags & XLOG_INCLUDE_XID)
214-
MarkSubTransactionAssigned();
215-
216213
for (i = 0; i < max_registered_block_id; i++)
217214
registered_buffers[i].in_use = false;
218215

@@ -409,8 +406,6 @@ XLogRegisterBufData(uint8 block_id, char *data, int len)
409406
* - XLOG_MARK_UNIMPORTANT, to signal that the record is not important for
410407
* durability, which allows to avoid triggering WAL archiving and other
411408
* background activity.
412-
* - XLOG_INCLUDE_XID, a message-passing hack between XLogRecordAssemble
413-
* and XLogResetInsertion.
414409
*/
415410
void
416411
XLogSetRecordFlags(uint8 flags)
@@ -465,6 +460,7 @@ XLogInsert(RmgrId rmid, uint8 info)
465460
{
466461
XLogRecPtr RedoRecPtr;
467462
bool doPageWrites;
463+
bool topxid_included = false;
468464
XLogRecPtr fpw_lsn;
469465
XLogRecData *rdt;
470466
int num_fpi = 0;
@@ -477,9 +473,10 @@ XLogInsert(RmgrId rmid, uint8 info)
477473
GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites);
478474

479475
rdt = XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites,
480-
&fpw_lsn, &num_fpi);
476+
&fpw_lsn, &num_fpi, &topxid_included);
481477

482-
EndPos = XLogInsertRecord(rdt, fpw_lsn, curinsert_flags, num_fpi);
478+
EndPos = XLogInsertRecord(rdt, fpw_lsn, curinsert_flags, num_fpi,
479+
topxid_included);
483480
} while (EndPos == InvalidXLogRecPtr);
484481

485482
XLogResetInsertion();
@@ -498,11 +495,14 @@ XLogInsert(RmgrId rmid, uint8 info)
498495
* of all of them, *fpw_lsn is set to the lowest LSN among such pages. This
499496
* signals that the assembled record is only good for insertion on the
500497
* assumption that the RedoRecPtr and doPageWrites values were up-to-date.
498+
*
499+
* *topxid_included is set if the topmost transaction ID is logged with the
500+
* current subtransaction.
501501
*/
502502
static XLogRecData *
503503
XLogRecordAssemble(RmgrId rmid, uint8 info,
504504
XLogRecPtr RedoRecPtr, bool doPageWrites,
505-
XLogRecPtr *fpw_lsn, int *num_fpi)
505+
XLogRecPtr *fpw_lsn, int *num_fpi, bool *topxid_included)
506506
{
507507
XLogRecData *rdt;
508508
uint32 total_len = 0;
@@ -788,12 +788,12 @@ XLogRecordAssemble(RmgrId rmid, uint8 info,
788788
}
789789

790790
/* followed by toplevel XID, if not already included in previous record */
791-
if (IsSubTransactionAssignmentPending())
791+
if (IsSubxactTopXidLogPending())
792792
{
793793
TransactionId xid = GetTopTransactionIdIfAny();
794794

795-
/* update the flag (later used by XLogResetInsertion) */
796-
XLogSetRecordFlags(XLOG_INCLUDE_XID);
795+
/* Set the flag that the top xid is included in the WAL */
796+
*topxid_included = true;
797797

798798
*(scratch++) = (char) XLR_BLOCK_ID_TOPLEVEL_XID;
799799
memcpy(scratch, &xid, sizeof(TransactionId));

src/include/access/xact.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,8 @@ extern void UnregisterXactCallback(XactCallback callback, void *arg);
433433
extern void RegisterSubXactCallback(SubXactCallback callback, void *arg);
434434
extern void UnregisterSubXactCallback(SubXactCallback callback, void *arg);
435435

436-
extern bool IsSubTransactionAssignmentPending(void);
437-
extern void MarkSubTransactionAssigned(void);
436+
extern bool IsSubxactTopXidLogPending(void);
437+
extern void MarkSubxactTopXidLogged(void);
438438

439439
extern int xactGetCommittedChildren(TransactionId **ptr);
440440

src/include/access/xlog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ extern bool XLOG_DEBUG;
212212
*/
213213
#define XLOG_INCLUDE_ORIGIN 0x01 /* include the replication origin */
214214
#define XLOG_MARK_UNIMPORTANT 0x02 /* record not important for durability */
215-
#define XLOG_INCLUDE_XID 0x04 /* WAL-internal message-passing hack */
216215

217216

218217
/* Checkpoint statistics */
@@ -258,7 +257,8 @@ struct XLogRecData;
258257
extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata,
259258
XLogRecPtr fpw_lsn,
260259
uint8 flags,
261-
int num_fpi);
260+
int num_fpi,
261+
bool topxid_included);
262262
extern void XLogFlush(XLogRecPtr RecPtr);
263263
extern bool XLogBackgroundFlush(void);
264264
extern bool XLogNeedsFlush(XLogRecPtr RecPtr);

0 commit comments

Comments
 (0)