Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b3a5d01

Browse files
committed
Refactor setting XLP_FIRST_IS_OVERWRITE_CONTRECORD.
Set it directly in CreateOverwriteContrecordRecord(). That way, AdvanceXLInsertBuffer() doesn't need the missingContrecPtr global variable. This is in preparation for splitting xlog.c into multiple files. Reviewed-by: Robert Haas Discussion: https://www.postgresql.org/message-id/a462d79c-cb5a-47cc-e9ac-616b5003965f%40iki.fi
1 parent d231be0 commit b3a5d01

File tree

1 file changed

+53
-20
lines changed
  • src/backend/access/transam

1 file changed

+53
-20
lines changed

src/backend/access/transam/xlog.c

+53-20
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,9 @@ static void VerifyOverwriteContrecord(xl_overwrite_contrecord *xlrec,
913913
XLogReaderState *state);
914914
static int LocalSetXLogInsertAllowed(void);
915915
static void CreateEndOfRecoveryRecord(void);
916-
static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn);
916+
static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn,
917+
XLogRecPtr missingContrecPtr,
918+
TimeLineID newTLI);
917919
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
918920
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo);
919921
static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void);
@@ -2295,18 +2297,6 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
22952297
if (!Insert->forcePageWrites)
22962298
NewPage->xlp_info |= XLP_BKP_REMOVABLE;
22972299

2298-
/*
2299-
* If a record was found to be broken at the end of recovery, and
2300-
* we're going to write on the page where its first contrecord was
2301-
* lost, set the XLP_FIRST_IS_OVERWRITE_CONTRECORD flag on the page
2302-
* header. See CreateOverwriteContrecordRecord().
2303-
*/
2304-
if (missingContrecPtr == NewPageBeginPtr)
2305-
{
2306-
NewPage->xlp_info |= XLP_FIRST_IS_OVERWRITE_CONTRECORD;
2307-
missingContrecPtr = InvalidXLogRecPtr;
2308-
}
2309-
23102300
/*
23112301
* If first page of an XLOG segment file, make it a long header.
23122302
*/
@@ -8149,7 +8139,7 @@ StartupXLOG(void)
81498139
if (!XLogRecPtrIsInvalid(abortedRecPtr))
81508140
{
81518141
Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
8152-
CreateOverwriteContrecordRecord(abortedRecPtr);
8142+
CreateOverwriteContrecordRecord(abortedRecPtr, missingContrecPtr, newTLI);
81538143
abortedRecPtr = InvalidXLogRecPtr;
81548144
missingContrecPtr = InvalidXLogRecPtr;
81558145
}
@@ -9530,27 +9520,70 @@ CreateEndOfRecoveryRecord(void)
95309520
* skip the record it was reading, and pass back the LSN of the skipped
95319521
* record, so that its caller can verify (on "replay" of that record) that the
95329522
* XLOG_OVERWRITE_CONTRECORD matches what was effectively overwritten.
9523+
*
9524+
* 'aborted_lsn' is the beginning position of the record that was incomplete.
9525+
* It is included in the WAL record. 'pagePtr' and 'newTLI' point to the
9526+
* beginning of the XLOG page where the record is to be inserted. They must
9527+
* match the current WAL insert position, they're passed here just so that we
9528+
* can verify that.
95339529
*/
95349530
static XLogRecPtr
9535-
CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn)
9531+
CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn, XLogRecPtr pagePtr,
9532+
TimeLineID newTLI)
95369533
{
95379534
xl_overwrite_contrecord xlrec;
95389535
XLogRecPtr recptr;
9536+
XLogPageHeader pagehdr;
9537+
XLogRecPtr startPos;
95399538

9540-
/* sanity check */
9539+
/* sanity checks */
95419540
if (!RecoveryInProgress())
95429541
elog(ERROR, "can only be used at end of recovery");
9543-
9544-
xlrec.overwritten_lsn = aborted_lsn;
9545-
xlrec.overwrite_time = GetCurrentTimestamp();
9542+
if (pagePtr % XLOG_BLCKSZ != 0)
9543+
elog(ERROR, "invalid position for missing continuation record %X/%X",
9544+
LSN_FORMAT_ARGS(pagePtr));
9545+
9546+
/* The current WAL insert position should be right after the page header */
9547+
startPos = pagePtr;
9548+
if (XLogSegmentOffset(startPos, wal_segment_size) == 0)
9549+
startPos += SizeOfXLogLongPHD;
9550+
else
9551+
startPos += SizeOfXLogShortPHD;
9552+
recptr = GetXLogInsertRecPtr();
9553+
if (recptr != startPos)
9554+
elog(ERROR, "invalid WAL insert position %X/%X for OVERWRITE_CONTRECORD",
9555+
LSN_FORMAT_ARGS(recptr));
95469556

95479557
START_CRIT_SECTION();
95489558

9559+
/*
9560+
* Initialize the XLOG page header (by GetXLogBuffer), and set the
9561+
* XLP_FIRST_IS_OVERWRITE_CONTRECORD flag.
9562+
*
9563+
* No other backend is allowed to write WAL yet, so acquiring the WAL
9564+
* insertion lock is just pro forma.
9565+
*/
9566+
WALInsertLockAcquire();
9567+
pagehdr = (XLogPageHeader) GetXLogBuffer(pagePtr, newTLI);
9568+
pagehdr->xlp_info |= XLP_FIRST_IS_OVERWRITE_CONTRECORD;
9569+
WALInsertLockRelease();
9570+
9571+
/*
9572+
* Insert the XLOG_OVERWRITE_CONTRECORD record as the first record on the
9573+
* page. We know it becomes the first record, because no other backend is
9574+
* allowed to write WAL yet.
9575+
*/
95499576
XLogBeginInsert();
9577+
xlrec.overwritten_lsn = aborted_lsn;
9578+
xlrec.overwrite_time = GetCurrentTimestamp();
95509579
XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
9551-
95529580
recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
95539581

9582+
/* check that the record was inserted to the right place */
9583+
if (ProcLastRecPtr != startPos)
9584+
elog(ERROR, "OVERWRITE_CONTRECORD was inserted to unexpected position %X/%X",
9585+
LSN_FORMAT_ARGS(ProcLastRecPtr));
9586+
95549587
XLogFlush(recptr);
95559588

95569589
END_CRIT_SECTION();

0 commit comments

Comments
 (0)