summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xlog.c155
-rw-r--r--src/include/access/xlog.h10
2 files changed, 92 insertions, 73 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 912a913b64..3c6eafaf92 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -665,6 +665,7 @@ static void UpdateLastRemovedPtr(char *filename);
static void ValidateXLOGDirectoryStructure(void);
static void CleanupBackupHistory(void);
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force);
+static void XLogAcceptWrites(XLogAcceptWritesInfo *awi);
static void InitControlFile(uint64 sysidentifier);
static void WriteControlFile(void);
static void ReadControlFile(void);
@@ -4887,13 +4888,8 @@ StartupXLOG(void)
bool didCrash;
bool haveTblspcMap;
bool haveBackupLabel;
- XLogRecPtr EndOfLog;
- TimeLineID EndOfLogTLI;
- TimeLineID newTLI;
- bool performedWalRecovery;
EndOfWalRecoveryInfo *endOfRecoveryInfo;
- XLogRecPtr abortedRecPtr;
- XLogRecPtr missingContrecPtr;
+ XLogAcceptWritesInfo awi;
TransactionId oldestActiveXID;
/*
@@ -5293,19 +5289,19 @@ StartupXLOG(void)
* We're all set for replaying the WAL now. Do it.
*/
PerformWalRecovery();
- performedWalRecovery = true;
+ awi.performedWalRecovery = true;
}
else
- performedWalRecovery = false;
+ awi.performedWalRecovery = false;
/*
* Finish WAL recovery.
*/
endOfRecoveryInfo = FinishWalRecovery();
- EndOfLog = endOfRecoveryInfo->endOfLog;
- EndOfLogTLI = endOfRecoveryInfo->endOfLogTLI;
- abortedRecPtr = endOfRecoveryInfo->abortedRecPtr;
- missingContrecPtr = endOfRecoveryInfo->missingContrecPtr;
+ awi.EndOfLog = endOfRecoveryInfo->endOfLog;
+ awi.EndOfLogTLI = endOfRecoveryInfo->endOfLogTLI;
+ awi.abortedRecPtr = endOfRecoveryInfo->abortedRecPtr;
+ awi.missingContrecPtr = endOfRecoveryInfo->missingContrecPtr;
/*
* When recovering from a backup (we are in recovery, and archive recovery
@@ -5326,7 +5322,7 @@ StartupXLOG(void)
* been advanced beyond the WAL we processed.
*/
if (InRecovery &&
- (EndOfLog < LocalMinRecoveryPoint ||
+ (awi.EndOfLog < LocalMinRecoveryPoint ||
!XLogRecPtrIsInvalid(ControlFile->backupStartPoint)))
{
/*
@@ -5386,19 +5382,19 @@ StartupXLOG(void)
*
* In a normal crash recovery, we can just extend the timeline we were in.
*/
- newTLI = endOfRecoveryInfo->lastRecTLI;
+ awi.newTLI = endOfRecoveryInfo->lastRecTLI;
if (ArchiveRecoveryRequested)
{
- newTLI = findNewestTimeLine(recoveryTargetTLI) + 1;
+ awi.newTLI = findNewestTimeLine(recoveryTargetTLI) + 1;
ereport(LOG,
- (errmsg("selected new timeline ID: %u", newTLI)));
+ (errmsg("selected new timeline ID: %u", awi.newTLI)));
/*
* Make a writable copy of the last WAL segment. (Note that we also
* have a copy of the last block of the old WAL in
* endOfRecovery->lastPage; we will use that below.)
*/
- XLogInitNewTimeline(EndOfLogTLI, EndOfLog, newTLI);
+ XLogInitNewTimeline(awi.EndOfLogTLI, awi.EndOfLog, awi.newTLI);
/*
* Remove the signal files out of the way, so that we don't
@@ -5420,15 +5416,16 @@ StartupXLOG(void)
* To minimize the window for that, try to do as little as possible
* between here and writing the end-of-recovery record.
*/
- writeTimeLineHistory(newTLI, recoveryTargetTLI,
- EndOfLog, endOfRecoveryInfo->recoveryStopReason);
+ writeTimeLineHistory(awi.newTLI, recoveryTargetTLI,
+ awi.EndOfLog,
+ endOfRecoveryInfo->recoveryStopReason);
ereport(LOG,
(errmsg("archive recovery complete")));
}
/* Save the selected TimeLineID in shared memory, too */
- XLogCtl->InsertTimeLineID = newTLI;
+ XLogCtl->InsertTimeLineID = awi.newTLI;
XLogCtl->PrevTimeLineID = endOfRecoveryInfo->lastRecTLI;
/*
@@ -5437,10 +5434,10 @@ StartupXLOG(void)
* (It's critical to first write an OVERWRITE_CONTRECORD message, which
* we'll do as soon as we're open for writing new WAL.)
*/
- if (!XLogRecPtrIsInvalid(missingContrecPtr))
+ if (!XLogRecPtrIsInvalid(awi.missingContrecPtr))
{
- Assert(!XLogRecPtrIsInvalid(abortedRecPtr));
- EndOfLog = missingContrecPtr;
+ Assert(!XLogRecPtrIsInvalid(awi.abortedRecPtr));
+ awi.EndOfLog = awi.missingContrecPtr;
}
/*
@@ -5450,21 +5447,21 @@ StartupXLOG(void)
*/
Insert = &XLogCtl->Insert;
Insert->PrevBytePos = XLogRecPtrToBytePos(endOfRecoveryInfo->lastRec);
- Insert->CurrBytePos = XLogRecPtrToBytePos(EndOfLog);
+ Insert->CurrBytePos = XLogRecPtrToBytePos(awi.EndOfLog);
/*
* Tricky point here: lastPage contains the *last* block that the LastRec
* record spans, not the one it starts in. The last block is indeed the
* one we want to use.
*/
- if (EndOfLog % XLOG_BLCKSZ != 0)
+ if (awi.EndOfLog % XLOG_BLCKSZ != 0)
{
char *page;
int len;
int firstIdx;
- firstIdx = XLogRecPtrToBufIdx(EndOfLog);
- len = EndOfLog - endOfRecoveryInfo->lastPageBeginPtr;
+ firstIdx = XLogRecPtrToBufIdx(awi.EndOfLog);
+ len = awi.EndOfLog - endOfRecoveryInfo->lastPageBeginPtr;
Assert(len < XLOG_BLCKSZ);
/* Copy the valid part of the last block, and zero the rest */
@@ -5482,20 +5479,20 @@ StartupXLOG(void)
* let the first attempt to insert a log record to initialize the next
* buffer.
*/
- XLogCtl->InitializedUpTo = EndOfLog;
+ XLogCtl->InitializedUpTo = awi.EndOfLog;
}
- LogwrtResult.Write = LogwrtResult.Flush = EndOfLog;
+ LogwrtResult.Write = LogwrtResult.Flush = awi.EndOfLog;
XLogCtl->LogwrtResult = LogwrtResult;
- XLogCtl->LogwrtRqst.Write = EndOfLog;
- XLogCtl->LogwrtRqst.Flush = EndOfLog;
+ XLogCtl->LogwrtRqst.Write = awi.EndOfLog;
+ XLogCtl->LogwrtRqst.Flush = awi.EndOfLog;
/*
* Preallocate additional log files, if wanted.
*/
- PreallocXlogFiles(EndOfLog, newTLI);
+ PreallocXlogFiles(awi.EndOfLog, awi.newTLI);
/*
* Okay, we're officially UP.
@@ -5504,7 +5501,7 @@ StartupXLOG(void)
/* start the archive_timeout timer and LSN running */
XLogCtl->lastSegSwitchTime = (pg_time_t) time(NULL);
- XLogCtl->lastSegSwitchLSN = EndOfLog;
+ XLogCtl->lastSegSwitchLSN = awi.EndOfLog;
/* also initialize latestCompletedXid, to nextXid - 1 */
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
@@ -5531,45 +5528,8 @@ StartupXLOG(void)
/* Shut down xlogreader */
ShutdownWalRecovery();
- /* Enable WAL writes for this backend only. */
- LocalSetXLogInsertAllowed();
-
- /* If necessary, write overwrite-contrecord before doing anything else */
- if (!XLogRecPtrIsInvalid(abortedRecPtr))
- {
- Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
- CreateOverwriteContrecordRecord(abortedRecPtr, missingContrecPtr, newTLI);
- }
-
- /*
- * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
- * record before resource manager writes cleanup WAL records or checkpoint
- * record is written.
- */
- Insert->fullPageWrites = lastFullPageWrites;
- UpdateFullPageWrites();
-
- /*
- * Emit end-of-recovery record in XLOG, if required.
- */
- if (performedWalRecovery)
- CreateEndOfRecoveryRecord();
-
- /*
- * If any of the critical GUCs have changed, log them before we allow
- * backends to write WAL.
- */
- XLogReportParameters();
-
- /* If this is archive recovery, perform post-recovery cleanup actions. */
- if (ArchiveRecoveryRequested)
- CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog, newTLI);
-
- /*
- * Local WAL inserts enabled, so it's time to finish initialization of
- * commit timestamp.
- */
- CompleteCommitTsInitialization();
+ /* WRITE A BETTER COMMENT */
+ XLogAcceptWrites(&awi);
/*
* All done with end-of-recovery actions.
@@ -5620,10 +5580,59 @@ StartupXLOG(void)
* back, and in case of a crash, recovering from it might take a longer
* than is appropriate now that we're not in standby mode anymore.
*/
- if (performedWalRecovery)
+ if (awi.performedWalRecovery)
RequestCheckpoint(CHECKPOINT_FORCE);
}
+static void
+XLogAcceptWrites(XLogAcceptWritesInfo *awi)
+{
+ XLogCtlInsert *Insert = &XLogCtl->Insert;
+
+ /* Enable WAL writes for this backend only. */
+ LocalSetXLogInsertAllowed();
+
+ /* If necessary, write overwrite-contrecord before doing anything else */
+ if (!XLogRecPtrIsInvalid(awi->abortedRecPtr))
+ {
+ Assert(!XLogRecPtrIsInvalid(awi->missingContrecPtr));
+ CreateOverwriteContrecordRecord(awi->abortedRecPtr,
+ awi->missingContrecPtr,
+ awi->newTLI);
+ }
+
+ /*
+ * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
+ * record before resource manager writes cleanup WAL records or checkpoint
+ * record is written.
+ */
+ Insert->fullPageWrites = lastFullPageWrites;
+ UpdateFullPageWrites();
+
+ /*
+ * Emit end-of-recovery record in XLOG, if required.
+ */
+ if (awi->performedWalRecovery)
+ CreateEndOfRecoveryRecord();
+
+ /*
+ * If any of the critical GUCs have changed, log them before we allow
+ * backends to write WAL.
+ */
+ XLogReportParameters();
+
+ /* If this is archive recovery, perform post-recovery cleanup actions. */
+ if (ArchiveRecoveryRequested)
+ CleanupAfterArchiveRecovery(awi->EndOfLogTLI, awi->EndOfLog,
+ awi->newTLI);
+
+ /*
+ * Local WAL inserts enabled, so it's time to finish initialization of
+ * commit timestamp.
+ */
+ CompleteCommitTsInitialization();
+}
+
/*
* Callback from PerformWalRecovery(), called when we switch from crash
* recovery to archive recovery mode. Updates the control file accordingly.
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 04091d8576..ab557637c8 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -174,6 +174,16 @@ typedef struct CheckpointStatsData
* entire sync phase. */
} CheckpointStatsData;
+typedef struct XLogAcceptWritesInfo
+{
+ bool performedWalRecovery;
+ XLogRecPtr abortedRecPtr;
+ XLogRecPtr missingContrecPtr;
+ XLogRecPtr EndOfLog;
+ TimeLineID EndOfLogTLI;
+ TimeLineID newTLI;
+} XLogAcceptWritesInfo;
+
extern PGDLLIMPORT CheckpointStatsData CheckpointStats;
/*