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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy