@@ -417,26 +417,12 @@ static void TerminateChildren(int signal);
417
417
418
418
static int CountChildren (int target );
419
419
static Backend * assign_backendlist_entry (void );
420
+ static void LaunchMissingBackgroundProcesses (void );
420
421
static void maybe_start_bgworkers (void );
421
422
static bool CreateOptsFile (int argc , char * argv [], char * fullprogname );
422
423
static pid_t StartChildProcess (BackendType type );
423
424
static void StartAutovacuumWorker (void );
424
- static void MaybeStartWalReceiver (void );
425
- static void MaybeStartWalSummarizer (void );
426
425
static void InitPostmasterDeathWatchHandle (void );
427
- static void MaybeStartSlotSyncWorker (void );
428
-
429
- /*
430
- * Archiver is allowed to start up at the current postmaster state?
431
- *
432
- * If WAL archiving is enabled always, we are allowed to start archiver
433
- * even during recovery.
434
- */
435
- #define PgArchStartupAllowed () \
436
- (((XLogArchivingActive() && pmState == PM_RUN) || \
437
- (XLogArchivingAlways() && \
438
- (pmState == PM_RECOVERY || pmState == PM_HOT_STANDBY))) && \
439
- PgArchCanRestart())
440
426
441
427
#ifdef WIN32
442
428
#define WNOHANG 0 /* ignored, so any integer value will do */
@@ -1670,53 +1656,11 @@ ServerLoop(void)
1670
1656
}
1671
1657
}
1672
1658
1673
- /* If we have lost the log collector, try to start a new one */
1674
- if (SysLoggerPID == 0 && Logging_collector )
1675
- SysLoggerPID = SysLogger_Start ();
1676
-
1677
- /*
1678
- * If no background writer process is running, and we are not in a
1679
- * state that prevents it, start one. It doesn't matter if this
1680
- * fails, we'll just try again later. Likewise for the checkpointer.
1681
- */
1682
- if (pmState == PM_RUN || pmState == PM_RECOVERY ||
1683
- pmState == PM_HOT_STANDBY || pmState == PM_STARTUP )
1684
- {
1685
- if (CheckpointerPID == 0 )
1686
- CheckpointerPID = StartChildProcess (B_CHECKPOINTER );
1687
- if (BgWriterPID == 0 )
1688
- BgWriterPID = StartChildProcess (B_BG_WRITER );
1689
- }
1690
-
1691
1659
/*
1692
- * Likewise, if we have lost the walwriter process, try to start a new
1693
- * one. But this is needed only in normal operation (else we cannot
1694
- * be writing any new WAL).
1660
+ * If we need to launch any background processes after changing state
1661
+ * or because some exited, do so now.
1695
1662
*/
1696
- if (WalWriterPID == 0 && pmState == PM_RUN )
1697
- WalWriterPID = StartChildProcess (B_WAL_WRITER );
1698
-
1699
- /*
1700
- * If we have lost the autovacuum launcher, try to start a new one. We
1701
- * don't want autovacuum to run in binary upgrade mode because
1702
- * autovacuum might update relfrozenxid for empty tables before the
1703
- * physical files are put in place.
1704
- */
1705
- if (!IsBinaryUpgrade && AutoVacPID == 0 &&
1706
- (AutoVacuumingActive () || start_autovac_launcher ) &&
1707
- pmState == PM_RUN )
1708
- {
1709
- AutoVacPID = StartChildProcess (B_AUTOVAC_LAUNCHER );
1710
- if (AutoVacPID != 0 )
1711
- start_autovac_launcher = false; /* signal processed */
1712
- }
1713
-
1714
- /* If we have lost the archiver, try to start a new one. */
1715
- if (PgArchPID == 0 && PgArchStartupAllowed ())
1716
- PgArchPID = StartChildProcess (B_ARCHIVER );
1717
-
1718
- /* If we need to start a slot sync worker, try to do that now */
1719
- MaybeStartSlotSyncWorker ();
1663
+ LaunchMissingBackgroundProcesses ();
1720
1664
1721
1665
/* If we need to signal the autovacuum launcher, do so now */
1722
1666
if (avlauncher_needs_signal )
@@ -1726,17 +1670,6 @@ ServerLoop(void)
1726
1670
kill (AutoVacPID , SIGUSR2 );
1727
1671
}
1728
1672
1729
- /* If we need to start a WAL receiver, try to do that now */
1730
- if (WalReceiverRequested )
1731
- MaybeStartWalReceiver ();
1732
-
1733
- /* If we need to start a WAL summarizer, try to do that now */
1734
- MaybeStartWalSummarizer ();
1735
-
1736
- /* Get other worker processes running, if needed */
1737
- if (StartWorkerNeeded || HaveCrashedWorker )
1738
- maybe_start_bgworkers ();
1739
-
1740
1673
#ifdef HAVE_PTHREAD_IS_THREADED_NP
1741
1674
1742
1675
/*
@@ -2386,23 +2319,11 @@ process_pm_child_exit(void)
2386
2319
connsAllowed = true;
2387
2320
2388
2321
/*
2389
- * Crank up any background tasks that we didn't start earlier
2390
- * already. It doesn't matter if any of these fail, we'll just
2391
- * try again later .
2322
+ * At the next iteration of the postmaster's main loop, we will
2323
+ * crank up the background tasks like the autovacuum launcher and
2324
+ * background workers that were not started earlier already .
2392
2325
*/
2393
- if (CheckpointerPID == 0 )
2394
- CheckpointerPID = StartChildProcess (B_CHECKPOINTER );
2395
- if (BgWriterPID == 0 )
2396
- BgWriterPID = StartChildProcess (B_BG_WRITER );
2397
- if (WalWriterPID == 0 )
2398
- WalWriterPID = StartChildProcess (B_WAL_WRITER );
2399
- MaybeStartWalSummarizer ();
2400
- if (!IsBinaryUpgrade && AutoVacuumingActive () && AutoVacPID == 0 )
2401
- AutoVacPID = StartChildProcess (B_AUTOVAC_LAUNCHER );
2402
- if (PgArchStartupAllowed () && PgArchPID == 0 )
2403
- PgArchPID = StartChildProcess (B_ARCHIVER );
2404
- MaybeStartSlotSyncWorker ();
2405
- maybe_start_bgworkers ();
2326
+ StartWorkerNeeded = true;
2406
2327
2407
2328
/* at this point we are really open for business */
2408
2329
ereport (LOG ,
@@ -2541,20 +2462,15 @@ process_pm_child_exit(void)
2541
2462
/*
2542
2463
* Was it the archiver? If exit status is zero (normal) or one (FATAL
2543
2464
* exit), we assume everything is all right just like normal backends
2544
- * and just try to restart a new one so that we immediately retry
2545
- * archiving remaining files. (If fail, we'll try again in future
2546
- * cycles of the postmaster's main loop.) Unless we were waiting for
2547
- * it to shut down; don't restart it in that case, and
2548
- * PostmasterStateMachine() will advance to the next shutdown step.
2465
+ * and just try to start a new one on the next cycle of the
2466
+ * postmaster's main loop, to retry archiving remaining files.
2549
2467
*/
2550
2468
if (pid == PgArchPID )
2551
2469
{
2552
2470
PgArchPID = 0 ;
2553
2471
if (!EXIT_STATUS_0 (exitstatus ) && !EXIT_STATUS_1 (exitstatus ))
2554
2472
HandleChildCrash (pid , exitstatus ,
2555
2473
_ ("archiver process" ));
2556
- if (PgArchStartupAllowed ())
2557
- PgArchPID = StartChildProcess (B_ARCHIVER );
2558
2474
continue ;
2559
2475
}
2560
2476
@@ -3207,6 +3123,118 @@ PostmasterStateMachine(void)
3207
3123
}
3208
3124
}
3209
3125
3126
+ /*
3127
+ * Launch background processes after state change, or relaunch after an
3128
+ * existing process has exited.
3129
+ *
3130
+ * Check the current pmState and the status of any background processes. If
3131
+ * there are any background processes missing that should be running in the
3132
+ * current state, but are not, launch them.
3133
+ */
3134
+ static void
3135
+ LaunchMissingBackgroundProcesses (void )
3136
+ {
3137
+ /* Syslogger is active in all states */
3138
+ if (SysLoggerPID == 0 && Logging_collector )
3139
+ SysLoggerPID = SysLogger_Start ();
3140
+
3141
+ /*
3142
+ * The checkpointer and the background writer are active from the start,
3143
+ * until shutdown is initiated.
3144
+ *
3145
+ * (If the checkpointer is not running when we enter the the PM_SHUTDOWN
3146
+ * state, it is launched one more time to perform the shutdown checkpoint.
3147
+ * That's done in PostmasterStateMachine(), not here.)
3148
+ */
3149
+ if (pmState == PM_RUN || pmState == PM_RECOVERY ||
3150
+ pmState == PM_HOT_STANDBY || pmState == PM_STARTUP )
3151
+ {
3152
+ if (CheckpointerPID == 0 )
3153
+ CheckpointerPID = StartChildProcess (B_CHECKPOINTER );
3154
+ if (BgWriterPID == 0 )
3155
+ BgWriterPID = StartChildProcess (B_BG_WRITER );
3156
+ }
3157
+
3158
+ /*
3159
+ * WAL writer is needed only in normal operation (else we cannot be
3160
+ * writing any new WAL).
3161
+ */
3162
+ if (WalWriterPID == 0 && pmState == PM_RUN )
3163
+ WalWriterPID = StartChildProcess (B_WAL_WRITER );
3164
+
3165
+ /*
3166
+ * We don't want autovacuum to run in binary upgrade mode because
3167
+ * autovacuum might update relfrozenxid for empty tables before the
3168
+ * physical files are put in place.
3169
+ */
3170
+ if (!IsBinaryUpgrade && AutoVacPID == 0 &&
3171
+ (AutoVacuumingActive () || start_autovac_launcher ) &&
3172
+ pmState == PM_RUN )
3173
+ {
3174
+ AutoVacPID = StartChildProcess (B_AUTOVAC_LAUNCHER );
3175
+ if (AutoVacPID != 0 )
3176
+ start_autovac_launcher = false; /* signal processed */
3177
+ }
3178
+
3179
+ /*
3180
+ * If WAL archiving is enabled always, we are allowed to start archiver
3181
+ * even during recovery.
3182
+ */
3183
+ if (PgArchPID == 0 &&
3184
+ ((XLogArchivingActive () && pmState == PM_RUN ) ||
3185
+ (XLogArchivingAlways () && (pmState == PM_RECOVERY || pmState == PM_HOT_STANDBY ))) &&
3186
+ PgArchCanRestart ())
3187
+ PgArchPID = StartChildProcess (B_ARCHIVER );
3188
+
3189
+ /*
3190
+ * If we need to start a slot sync worker, try to do that now
3191
+ *
3192
+ * We allow to start the slot sync worker when we are on a hot standby,
3193
+ * fast or immediate shutdown is not in progress, slot sync parameters are
3194
+ * configured correctly, and it is the first time of worker's launch, or
3195
+ * enough time has passed since the worker was launched last.
3196
+ */
3197
+ if (SlotSyncWorkerPID == 0 && pmState == PM_HOT_STANDBY &&
3198
+ Shutdown <= SmartShutdown && sync_replication_slots &&
3199
+ ValidateSlotSyncParams (LOG ) && SlotSyncWorkerCanRestart ())
3200
+ SlotSyncWorkerPID = StartChildProcess (B_SLOTSYNC_WORKER );
3201
+
3202
+ /*
3203
+ * If we need to start a WAL receiver, try to do that now
3204
+ *
3205
+ * Note: if WalReceiverPID is already nonzero, it might seem that we
3206
+ * should clear WalReceiverRequested. However, there's a race condition
3207
+ * if the walreceiver terminates and the startup process immediately
3208
+ * requests a new one: it's quite possible to get the signal for the
3209
+ * request before reaping the dead walreceiver process. Better to risk
3210
+ * launching an extra walreceiver than to miss launching one we need. (The
3211
+ * walreceiver code has logic to recognize that it should go away if not
3212
+ * needed.)
3213
+ */
3214
+ if (WalReceiverRequested )
3215
+ {
3216
+ if (WalReceiverPID == 0 &&
3217
+ (pmState == PM_STARTUP || pmState == PM_RECOVERY ||
3218
+ pmState == PM_HOT_STANDBY ) &&
3219
+ Shutdown <= SmartShutdown )
3220
+ {
3221
+ WalReceiverPID = StartChildProcess (B_WAL_RECEIVER );
3222
+ if (WalReceiverPID != 0 )
3223
+ WalReceiverRequested = false;
3224
+ /* else leave the flag set, so we'll try again later */
3225
+ }
3226
+ }
3227
+
3228
+ /* If we need to start a WAL summarizer, try to do that now */
3229
+ if (summarize_wal && WalSummarizerPID == 0 &&
3230
+ (pmState == PM_RUN || pmState == PM_HOT_STANDBY ) &&
3231
+ Shutdown <= SmartShutdown )
3232
+ WalSummarizerPID = StartChildProcess (B_WAL_SUMMARIZER );
3233
+
3234
+ /* Get other worker processes running, if needed */
3235
+ if (StartWorkerNeeded || HaveCrashedWorker )
3236
+ maybe_start_bgworkers ();
3237
+ }
3210
3238
3211
3239
/*
3212
3240
* Send a signal to a postmaster child process
@@ -3558,9 +3586,6 @@ process_pm_pmsignal(void)
3558
3586
StartWorkerNeeded = true;
3559
3587
}
3560
3588
3561
- if (StartWorkerNeeded || HaveCrashedWorker )
3562
- maybe_start_bgworkers ();
3563
-
3564
3589
/* Tell syslogger to rotate logfile if requested */
3565
3590
if (SysLoggerPID != 0 )
3566
3591
{
@@ -3600,9 +3625,7 @@ process_pm_pmsignal(void)
3600
3625
if (CheckPostmasterSignal (PMSIGNAL_START_WALRECEIVER ))
3601
3626
{
3602
3627
/* Startup Process wants us to start the walreceiver process. */
3603
- /* Start immediately if possible, else remember request for later. */
3604
3628
WalReceiverRequested = true;
3605
- MaybeStartWalReceiver ();
3606
3629
}
3607
3630
3608
3631
/*
@@ -3796,64 +3819,6 @@ StartAutovacuumWorker(void)
3796
3819
}
3797
3820
}
3798
3821
3799
- /*
3800
- * MaybeStartWalReceiver
3801
- * Start the WAL receiver process, if not running and our state allows.
3802
- *
3803
- * Note: if WalReceiverPID is already nonzero, it might seem that we should
3804
- * clear WalReceiverRequested. However, there's a race condition if the
3805
- * walreceiver terminates and the startup process immediately requests a new
3806
- * one: it's quite possible to get the signal for the request before reaping
3807
- * the dead walreceiver process. Better to risk launching an extra
3808
- * walreceiver than to miss launching one we need. (The walreceiver code
3809
- * has logic to recognize that it should go away if not needed.)
3810
- */
3811
- static void
3812
- MaybeStartWalReceiver (void )
3813
- {
3814
- if (WalReceiverPID == 0 &&
3815
- (pmState == PM_STARTUP || pmState == PM_RECOVERY ||
3816
- pmState == PM_HOT_STANDBY ) &&
3817
- Shutdown <= SmartShutdown )
3818
- {
3819
- WalReceiverPID = StartChildProcess (B_WAL_RECEIVER );
3820
- if (WalReceiverPID != 0 )
3821
- WalReceiverRequested = false;
3822
- /* else leave the flag set, so we'll try again later */
3823
- }
3824
- }
3825
-
3826
- /*
3827
- * MaybeStartWalSummarizer
3828
- * Start the WAL summarizer process, if not running and our state allows.
3829
- */
3830
- static void
3831
- MaybeStartWalSummarizer (void )
3832
- {
3833
- if (summarize_wal && WalSummarizerPID == 0 &&
3834
- (pmState == PM_RUN || pmState == PM_HOT_STANDBY ) &&
3835
- Shutdown <= SmartShutdown )
3836
- WalSummarizerPID = StartChildProcess (B_WAL_SUMMARIZER );
3837
- }
3838
-
3839
-
3840
- /*
3841
- * MaybeStartSlotSyncWorker
3842
- * Start the slot sync worker, if not running and our state allows.
3843
- *
3844
- * We allow to start the slot sync worker when we are on a hot standby,
3845
- * fast or immediate shutdown is not in progress, slot sync parameters
3846
- * are configured correctly, and it is the first time of worker's launch,
3847
- * or enough time has passed since the worker was launched last.
3848
- */
3849
- static void
3850
- MaybeStartSlotSyncWorker (void )
3851
- {
3852
- if (SlotSyncWorkerPID == 0 && pmState == PM_HOT_STANDBY &&
3853
- Shutdown <= SmartShutdown && sync_replication_slots &&
3854
- ValidateSlotSyncParams (LOG ) && SlotSyncWorkerCanRestart ())
3855
- SlotSyncWorkerPID = StartChildProcess (B_SLOTSYNC_WORKER );
3856
- }
3857
3822
3858
3823
/*
3859
3824
* Create the opts file
0 commit comments