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
This commit is contained in:
parent
d231be00cb
commit
b3a5d01c05
|
@ -913,7 +913,9 @@ static void VerifyOverwriteContrecord(xl_overwrite_contrecord *xlrec,
|
||||||
XLogReaderState *state);
|
XLogReaderState *state);
|
||||||
static int LocalSetXLogInsertAllowed(void);
|
static int LocalSetXLogInsertAllowed(void);
|
||||||
static void CreateEndOfRecoveryRecord(void);
|
static void CreateEndOfRecoveryRecord(void);
|
||||||
static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn);
|
static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn,
|
||||||
|
XLogRecPtr missingContrecPtr,
|
||||||
|
TimeLineID newTLI);
|
||||||
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
|
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
|
||||||
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo);
|
static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo);
|
||||||
static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void);
|
static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void);
|
||||||
|
@ -2295,18 +2297,6 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
|
||||||
if (!Insert->forcePageWrites)
|
if (!Insert->forcePageWrites)
|
||||||
NewPage->xlp_info |= XLP_BKP_REMOVABLE;
|
NewPage->xlp_info |= XLP_BKP_REMOVABLE;
|
||||||
|
|
||||||
/*
|
|
||||||
* If a record was found to be broken at the end of recovery, and
|
|
||||||
* we're going to write on the page where its first contrecord was
|
|
||||||
* lost, set the XLP_FIRST_IS_OVERWRITE_CONTRECORD flag on the page
|
|
||||||
* header. See CreateOverwriteContrecordRecord().
|
|
||||||
*/
|
|
||||||
if (missingContrecPtr == NewPageBeginPtr)
|
|
||||||
{
|
|
||||||
NewPage->xlp_info |= XLP_FIRST_IS_OVERWRITE_CONTRECORD;
|
|
||||||
missingContrecPtr = InvalidXLogRecPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If first page of an XLOG segment file, make it a long header.
|
* If first page of an XLOG segment file, make it a long header.
|
||||||
*/
|
*/
|
||||||
|
@ -8149,7 +8139,7 @@ StartupXLOG(void)
|
||||||
if (!XLogRecPtrIsInvalid(abortedRecPtr))
|
if (!XLogRecPtrIsInvalid(abortedRecPtr))
|
||||||
{
|
{
|
||||||
Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
|
Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
|
||||||
CreateOverwriteContrecordRecord(abortedRecPtr);
|
CreateOverwriteContrecordRecord(abortedRecPtr, missingContrecPtr, newTLI);
|
||||||
abortedRecPtr = InvalidXLogRecPtr;
|
abortedRecPtr = InvalidXLogRecPtr;
|
||||||
missingContrecPtr = InvalidXLogRecPtr;
|
missingContrecPtr = InvalidXLogRecPtr;
|
||||||
}
|
}
|
||||||
|
@ -9530,27 +9520,70 @@ CreateEndOfRecoveryRecord(void)
|
||||||
* skip the record it was reading, and pass back the LSN of the skipped
|
* skip the record it was reading, and pass back the LSN of the skipped
|
||||||
* record, so that its caller can verify (on "replay" of that record) that the
|
* record, so that its caller can verify (on "replay" of that record) that the
|
||||||
* XLOG_OVERWRITE_CONTRECORD matches what was effectively overwritten.
|
* XLOG_OVERWRITE_CONTRECORD matches what was effectively overwritten.
|
||||||
|
*
|
||||||
|
* 'aborted_lsn' is the beginning position of the record that was incomplete.
|
||||||
|
* It is included in the WAL record. 'pagePtr' and 'newTLI' point to the
|
||||||
|
* beginning of the XLOG page where the record is to be inserted. They must
|
||||||
|
* match the current WAL insert position, they're passed here just so that we
|
||||||
|
* can verify that.
|
||||||
*/
|
*/
|
||||||
static XLogRecPtr
|
static XLogRecPtr
|
||||||
CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn)
|
CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn, XLogRecPtr pagePtr,
|
||||||
|
TimeLineID newTLI)
|
||||||
{
|
{
|
||||||
xl_overwrite_contrecord xlrec;
|
xl_overwrite_contrecord xlrec;
|
||||||
XLogRecPtr recptr;
|
XLogRecPtr recptr;
|
||||||
|
XLogPageHeader pagehdr;
|
||||||
|
XLogRecPtr startPos;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity checks */
|
||||||
if (!RecoveryInProgress())
|
if (!RecoveryInProgress())
|
||||||
elog(ERROR, "can only be used at end of recovery");
|
elog(ERROR, "can only be used at end of recovery");
|
||||||
|
if (pagePtr % XLOG_BLCKSZ != 0)
|
||||||
|
elog(ERROR, "invalid position for missing continuation record %X/%X",
|
||||||
|
LSN_FORMAT_ARGS(pagePtr));
|
||||||
|
|
||||||
xlrec.overwritten_lsn = aborted_lsn;
|
/* The current WAL insert position should be right after the page header */
|
||||||
xlrec.overwrite_time = GetCurrentTimestamp();
|
startPos = pagePtr;
|
||||||
|
if (XLogSegmentOffset(startPos, wal_segment_size) == 0)
|
||||||
|
startPos += SizeOfXLogLongPHD;
|
||||||
|
else
|
||||||
|
startPos += SizeOfXLogShortPHD;
|
||||||
|
recptr = GetXLogInsertRecPtr();
|
||||||
|
if (recptr != startPos)
|
||||||
|
elog(ERROR, "invalid WAL insert position %X/%X for OVERWRITE_CONTRECORD",
|
||||||
|
LSN_FORMAT_ARGS(recptr));
|
||||||
|
|
||||||
START_CRIT_SECTION();
|
START_CRIT_SECTION();
|
||||||
|
|
||||||
XLogBeginInsert();
|
/*
|
||||||
XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
|
* Initialize the XLOG page header (by GetXLogBuffer), and set the
|
||||||
|
* XLP_FIRST_IS_OVERWRITE_CONTRECORD flag.
|
||||||
|
*
|
||||||
|
* No other backend is allowed to write WAL yet, so acquiring the WAL
|
||||||
|
* insertion lock is just pro forma.
|
||||||
|
*/
|
||||||
|
WALInsertLockAcquire();
|
||||||
|
pagehdr = (XLogPageHeader) GetXLogBuffer(pagePtr, newTLI);
|
||||||
|
pagehdr->xlp_info |= XLP_FIRST_IS_OVERWRITE_CONTRECORD;
|
||||||
|
WALInsertLockRelease();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert the XLOG_OVERWRITE_CONTRECORD record as the first record on the
|
||||||
|
* page. We know it becomes the first record, because no other backend is
|
||||||
|
* allowed to write WAL yet.
|
||||||
|
*/
|
||||||
|
XLogBeginInsert();
|
||||||
|
xlrec.overwritten_lsn = aborted_lsn;
|
||||||
|
xlrec.overwrite_time = GetCurrentTimestamp();
|
||||||
|
XLogRegisterData((char *) &xlrec, sizeof(xl_overwrite_contrecord));
|
||||||
recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
|
recptr = XLogInsert(RM_XLOG_ID, XLOG_OVERWRITE_CONTRECORD);
|
||||||
|
|
||||||
|
/* check that the record was inserted to the right place */
|
||||||
|
if (ProcLastRecPtr != startPos)
|
||||||
|
elog(ERROR, "OVERWRITE_CONTRECORD was inserted to unexpected position %X/%X",
|
||||||
|
LSN_FORMAT_ARGS(ProcLastRecPtr));
|
||||||
|
|
||||||
XLogFlush(recptr);
|
XLogFlush(recptr);
|
||||||
|
|
||||||
END_CRIT_SECTION();
|
END_CRIT_SECTION();
|
||||||
|
|
Loading…
Reference in New Issue