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);
bool didCrash;
bool haveTblspcMap;
bool haveBackupLabel;
- XLogRecPtr EndOfLog;
- TimeLineID EndOfLogTLI;
- TimeLineID newTLI;
- bool performedWalRecovery;
EndOfWalRecoveryInfo *endOfRecoveryInfo;
- XLogRecPtr abortedRecPtr;
- XLogRecPtr missingContrecPtr;
+ XLogAcceptWritesInfo awi;
TransactionId oldestActiveXID;
/*
* 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
* been advanced beyond the WAL we processed.
*/
if (InRecovery &&
- (EndOfLog < LocalMinRecoveryPoint ||
+ (awi.EndOfLog < LocalMinRecoveryPoint ||
!XLogRecPtrIsInvalid(ControlFile->backupStartPoint)))
{
/*
*
* 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
* 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;
/*
* (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;
}
/*
*/
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 */
* 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.
/* 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);
/* 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.
* 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.