1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

Run checkpointer and bgwriter in crash recovery.

Start up the checkpointer and bgwriter during crash recovery (except in
--single mode), as we do for replication.  This wasn't done back in
commit cdd46c76 out of caution.  Now it seems like a better idea to make
the environment as similar as possible in both cases.  There may also be
some performance advantages.

Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: Aleksander Alekseev <aleksander@timescale.com>
Tested-by: Jakub Wartak <Jakub.Wartak@tomtom.com>
Discussion: https://postgr.es/m/CA%2BhUKGJ8NRsqgkZEnsnRc2MFROBV-jCnacbYvtpptK2A9YYp9Q%40mail.gmail.com
This commit is contained in:
Thomas Munro
2021-08-02 17:32:20 +12:00
parent 8b1de88b7c
commit 7ff23c6d27
6 changed files with 22 additions and 65 deletions

View File

@ -869,9 +869,6 @@ bool reachedConsistency = false;
static bool InRedo = false; static bool InRedo = false;
/* Have we launched bgwriter during recovery? */
static bool bgwriterLaunched = false;
/* For WALInsertLockAcquire/Release functions */ /* For WALInsertLockAcquire/Release functions */
static int MyLockNo = 0; static int MyLockNo = 0;
static bool holdingAllLocks = false; static bool holdingAllLocks = false;
@ -7311,25 +7308,15 @@ StartupXLOG(void)
/* Also ensure XLogReceiptTime has a sane value */ /* Also ensure XLogReceiptTime has a sane value */
XLogReceiptTime = GetCurrentTimestamp(); 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 * Let postmaster know we've started redo now, so that it can launch
* checkpointer to perform restartpoints. We don't bother during * the archiver if necessary.
* 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.
*/ */
if (ArchiveRecoveryRequested && IsUnderPostmaster) if (IsUnderPostmaster)
{
PublishStartupProcessInformation();
EnableSyncRequestForwarding();
SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED); SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
bgwriterLaunched = true;
}
/* /*
* Allow read-only connections immediately if we're consistent * Allow read-only connections immediately if we're consistent
@ -7903,7 +7890,7 @@ StartupXLOG(void)
* after we're fully out of recovery mode and already accepting * after we're fully out of recovery mode and already accepting
* queries. * queries.
*/ */
if (bgwriterLaunched) if (ArchiveRecoveryRequested && IsUnderPostmaster)
{ {
if (LocalPromoteIsTriggered) if (LocalPromoteIsTriggered)
{ {
@ -7927,7 +7914,11 @@ StartupXLOG(void)
CHECKPOINT_WAIT); CHECKPOINT_WAIT);
} }
else else
CreateCheckPoint(CHECKPOINT_END_OF_RECOVERY | CHECKPOINT_IMMEDIATE); {
RequestCheckpoint(CHECKPOINT_END_OF_RECOVERY |
CHECKPOINT_IMMEDIATE |
CHECKPOINT_WAIT);
}
} }
if (ArchiveRecoveryRequested) if (ArchiveRecoveryRequested)
@ -12182,7 +12173,7 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
* Request a restartpoint if we've replayed too much xlog since the * Request a restartpoint if we've replayed too much xlog since the
* last one. * last one.
*/ */
if (bgwriterLaunched) if (ArchiveRecoveryRequested && IsUnderPostmaster)
{ {
if (XLogCheckpointNeeded(readSegNo)) if (XLogCheckpointNeeded(readSegNo))
{ {

View File

@ -12,9 +12,6 @@
* *
* As of Postgres 9.2 the bgwriter no longer handles checkpoints. * 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). * Normal termination is by SIGTERM, which instructs the bgwriter to exit(0).
* Emergency termination is by SIGQUIT; like any backend, the bgwriter will * Emergency termination is by SIGQUIT; like any backend, the bgwriter will
* simply abort and exit on SIGQUIT. * simply abort and exit on SIGQUIT.

View File

@ -10,9 +10,6 @@
* fill WAL segments; the checkpointer itself doesn't watch for the * fill WAL segments; the checkpointer itself doesn't watch for the
* condition.) * 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 * Normal termination is by SIGUSR2, which instructs the checkpointer to
* execute a shutdown checkpoint and then exit(0). (All backends must be * execute a shutdown checkpoint and then exit(0). (All backends must be
* stopped before SIGUSR2 is issued!) Emergency termination is by SIGQUIT; * stopped before SIGUSR2 is issued!) Emergency termination is by SIGQUIT;

View File

@ -1403,6 +1403,12 @@ PostmasterMain(int argc, char *argv[])
*/ */
AddToDataDirLockFile(LOCK_FILE_LINE_PM_STATUS, PM_STATUS_STARTING); 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... * We're ready to rock and roll...
*/ */
@ -1765,7 +1771,7 @@ ServerLoop(void)
* fails, we'll just try again later. Likewise for the checkpointer. * fails, we'll just try again later. Likewise for the checkpointer.
*/ */
if (pmState == PM_RUN || pmState == PM_RECOVERY || if (pmState == PM_RUN || pmState == PM_RECOVERY ||
pmState == PM_HOT_STANDBY) pmState == PM_HOT_STANDBY || pmState == PM_STARTUP)
{ {
if (CheckpointerPID == 0) if (CheckpointerPID == 0)
CheckpointerPID = StartCheckpointer(); CheckpointerPID = StartCheckpointer();
@ -5161,15 +5167,6 @@ sigusr1_handler(SIGNAL_ARGS)
FatalError = false; FatalError = false;
AbortStartTime = 0; 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 * Start the archiver if we're responsible for (re-)archiving received
* files. * files.

View File

@ -129,10 +129,10 @@ InitSync(void)
{ {
/* /*
* Create pending-operations hashtable if we need it. Currently, we need * 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 * it if we are standalone (not under a postmaster) or if we are a
* or checkpointer auxiliary process. * checkpointer auxiliary process.
*/ */
if (!IsUnderPostmaster || AmStartupProcess() || AmCheckpointerProcess()) if (!IsUnderPostmaster || AmCheckpointerProcess())
{ {
HASHCTL hash_ctl; HASHCTL hash_ctl;
@ -589,27 +589,3 @@ RegisterSyncRequest(const FileTag *ftag, SyncRequestType type,
return ret; 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);
}

View File

@ -60,7 +60,6 @@ extern void SyncPreCheckpoint(void);
extern void SyncPostCheckpoint(void); extern void SyncPostCheckpoint(void);
extern void ProcessSyncRequests(void); extern void ProcessSyncRequests(void);
extern void RememberSyncRequest(const FileTag *ftag, SyncRequestType type); extern void RememberSyncRequest(const FileTag *ftag, SyncRequestType type);
extern void EnableSyncRequestForwarding(void);
extern bool RegisterSyncRequest(const FileTag *ftag, SyncRequestType type, extern bool RegisterSyncRequest(const FileTag *ftag, SyncRequestType type,
bool retryOnError); bool retryOnError);