static bool InRedo = false;
-/* Have we launched bgwriter during recovery? */
-static bool bgwriterLaunched = false;
-
/* For WALInsertLockAcquire/Release functions */
static int MyLockNo = 0;
static bool holdingAllLocks = false;
/* Also ensure XLogReceiptTime has a sane value */
XLogReceiptTime = GetCurrentTimestamp();
+ /* Allow ProcSendSignal() to find us, for buffer pin wakeups. */
+ PublishStartupProcessInformation();
+
/*
* Let postmaster know we've started redo now, so that it can launch
- * checkpointer to perform restartpoints. We don't bother during
- * crash recovery as restartpoints can only be performed during
- * archive recovery. And we'd like to keep crash recovery simple, to
- * avoid introducing bugs that could affect you when recovering after
- * crash.
- *
- * After this point, we can no longer assume that we're the only
- * process in addition to postmaster! Also, fsync requests are
- * subsequently to be handled by the checkpointer, not locally.
+ * the archiver if necessary.
*/
- if (ArchiveRecoveryRequested && IsUnderPostmaster)
- {
- PublishStartupProcessInformation();
- EnableSyncRequestForwarding();
+ if (IsUnderPostmaster)
SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
- bgwriterLaunched = true;
- }
/*
* Allow read-only connections immediately if we're consistent
* after we're fully out of recovery mode and already accepting
* queries.
*/
- if (bgwriterLaunched)
+ if (ArchiveRecoveryRequested && IsUnderPostmaster)
{
if (LocalPromoteIsTriggered)
{
CHECKPOINT_WAIT);
}
else
- CreateCheckPoint(CHECKPOINT_END_OF_RECOVERY | CHECKPOINT_IMMEDIATE);
+ {
+ RequestCheckpoint(CHECKPOINT_END_OF_RECOVERY |
+ CHECKPOINT_IMMEDIATE |
+ CHECKPOINT_WAIT);
+ }
}
if (ArchiveRecoveryRequested)
* Request a restartpoint if we've replayed too much xlog since the
* last one.
*/
- if (bgwriterLaunched)
+ if (ArchiveRecoveryRequested && IsUnderPostmaster)
{
if (XLogCheckpointNeeded(readSegNo))
{
*
* As of Postgres 9.2 the bgwriter no longer handles checkpoints.
*
- * The bgwriter is started by the postmaster as soon as the startup subprocess
- * finishes, or as soon as recovery begins if we are doing archive recovery.
- * It remains alive until the postmaster commands it to terminate.
* Normal termination is by SIGTERM, which instructs the bgwriter to exit(0).
* Emergency termination is by SIGQUIT; like any backend, the bgwriter will
* simply abort and exit on SIGQUIT.
* fill WAL segments; the checkpointer itself doesn't watch for the
* condition.)
*
- * The checkpointer is started by the postmaster as soon as the startup
- * subprocess finishes, or as soon as recovery begins if we are doing archive
- * recovery. It remains alive until the postmaster commands it to terminate.
* Normal termination is by SIGUSR2, which instructs the checkpointer to
* execute a shutdown checkpoint and then exit(0). (All backends must be
* stopped before SIGUSR2 is issued!) Emergency termination is by SIGQUIT;
*/
AddToDataDirLockFile(LOCK_FILE_LINE_PM_STATUS, PM_STATUS_STARTING);
+ /* Start bgwriter and checkpointer so they can help with recovery */
+ if (CheckpointerPID == 0)
+ CheckpointerPID = StartCheckpointer();
+ if (BgWriterPID == 0)
+ BgWriterPID = StartBackgroundWriter();
+
/*
* We're ready to rock and roll...
*/
* fails, we'll just try again later. Likewise for the checkpointer.
*/
if (pmState == PM_RUN || pmState == PM_RECOVERY ||
- pmState == PM_HOT_STANDBY)
+ pmState == PM_HOT_STANDBY || pmState == PM_STARTUP)
{
if (CheckpointerPID == 0)
CheckpointerPID = StartCheckpointer();
FatalError = false;
AbortStartTime = 0;
- /*
- * Crank up the background tasks. It doesn't matter if this fails,
- * we'll just try again later.
- */
- Assert(CheckpointerPID == 0);
- CheckpointerPID = StartCheckpointer();
- Assert(BgWriterPID == 0);
- BgWriterPID = StartBackgroundWriter();
-
/*
* Start the archiver if we're responsible for (re-)archiving received
* files.
{
/*
* Create pending-operations hashtable if we need it. Currently, we need
- * it if we are standalone (not under a postmaster) or if we are a startup
- * or checkpointer auxiliary process.
+ * it if we are standalone (not under a postmaster) or if we are a
+ * checkpointer auxiliary process.
*/
- if (!IsUnderPostmaster || AmStartupProcess() || AmCheckpointerProcess())
+ if (!IsUnderPostmaster || AmCheckpointerProcess())
{
HASHCTL hash_ctl;
return ret;
}
-
-/*
- * In archive recovery, we rely on checkpointer to do fsyncs, but we will have
- * already created the pendingOps during initialization of the startup
- * process. Calling this function drops the local pendingOps so that
- * subsequent requests will be forwarded to checkpointer.
- */
-void
-EnableSyncRequestForwarding(void)
-{
- /* Perform any pending fsyncs we may have queued up, then drop table */
- if (pendingOps)
- {
- ProcessSyncRequests();
- hash_destroy(pendingOps);
- }
- pendingOps = NULL;
-
- /*
- * We should not have any pending unlink requests, since mdunlink doesn't
- * queue unlink requests when isRedo.
- */
- Assert(pendingUnlinks == NIL);
-}
extern void SyncPostCheckpoint(void);
extern void ProcessSyncRequests(void);
extern void RememberSyncRequest(const FileTag *ftag, SyncRequestType type);
-extern void EnableSyncRequestForwarding(void);
extern bool RegisterSyncRequest(const FileTag *ftag, SyncRequestType type,
bool retryOnError);