@@ -275,6 +275,7 @@ static pid_t StartupPID = 0,
275
275
#define NoShutdown 0
276
276
#define SmartShutdown 1
277
277
#define FastShutdown 2
278
+ #define ImmediateShutdown 3
278
279
279
280
static int Shutdown = NoShutdown;
280
281
@@ -345,6 +346,10 @@ typedef enum
345
346
346
347
static PMState pmState = PM_INIT;
347
348
349
+ /* Start time of abort processing at immediate shutdown or child crash */
350
+ static time_t AbortStartTime;
351
+ #define SIGKILL_CHILDREN_AFTER_SECS 5
352
+
348
353
static bool ReachedNormalRunning = false; /* T if we've reached PM_RUN */
349
354
350
355
bool ClientAuthInProgress = false; /* T during new-client
@@ -421,6 +426,7 @@ static void RandomSalt(char *md5Salt);
421
426
static void signal_child(pid_t pid, int signal);
422
427
static bool SignalSomeChildren(int signal, int targets);
423
428
static bool SignalUnconnectedWorkers(int signal);
429
+ static void TerminateChildren(int signal);
424
430
425
431
#define SignalChildren(sig) SignalSomeChildren(sig, BACKEND_TYPE_ALL)
426
432
@@ -1427,8 +1433,18 @@ DetermineSleepTime(struct timeval * timeout)
1427
1433
if (Shutdown > NoShutdown ||
1428
1434
(!StartWorkerNeeded && !HaveCrashedWorker))
1429
1435
{
1430
- timeout->tv_sec = 60;
1431
- timeout->tv_usec = 0;
1436
+ if (AbortStartTime > 0)
1437
+ {
1438
+ /* remaining time, but at least 1 second */
1439
+ timeout->tv_sec = Min(SIGKILL_CHILDREN_AFTER_SECS -
1440
+ (time(NULL) - AbortStartTime), 1);
1441
+ timeout->tv_usec = 0;
1442
+ }
1443
+ else
1444
+ {
1445
+ timeout->tv_sec = 60;
1446
+ timeout->tv_usec = 0;
1447
+ }
1432
1448
return;
1433
1449
}
1434
1450
@@ -1660,6 +1676,28 @@ ServerLoop(void)
1660
1676
TouchSocketLockFiles();
1661
1677
last_touch_time = now;
1662
1678
}
1679
+
1680
+ /*
1681
+ * If we already sent SIGQUIT to children and they are slow to shut
1682
+ * down, it's time to send them SIGKILL. This doesn't happen normally,
1683
+ * but under certain conditions backends can get stuck while shutting
1684
+ * down. This is a last measure to get them unwedged.
1685
+ *
1686
+ * Note we also do this during recovery from a process crash.
1687
+ */
1688
+ if ((Shutdown >= ImmediateShutdown || (FatalError && !SendStop)) &&
1689
+ now - AbortStartTime >= SIGKILL_CHILDREN_AFTER_SECS)
1690
+ {
1691
+ /* We were gentle with them before. Not anymore */
1692
+ TerminateChildren(SIGKILL);
1693
+
1694
+ /*
1695
+ * Additionally, unless we're recovering from a process crash, it's
1696
+ * now the time for postmaster to abandon ship.
1697
+ */
1698
+ if (!FatalError)
1699
+ ExitPostmaster(1);
1700
+ }
1663
1701
}
1664
1702
}
1665
1703
@@ -2455,30 +2493,27 @@ pmdie(SIGNAL_ARGS)
2455
2493
/*
2456
2494
* Immediate Shutdown:
2457
2495
*
2458
- * abort all children with SIGQUIT and exit without attempt to
2459
- * properly shut down data base system.
2496
+ * abort all children with SIGQUIT, wait for them to exit,
2497
+ * terminate remaining ones with SIGKILL, then exit without
2498
+ * attempt to properly shut down the data base system.
2460
2499
*/
2500
+ if (Shutdown >= ImmediateShutdown)
2501
+ break;
2502
+ Shutdown = ImmediateShutdown;
2461
2503
ereport(LOG,
2462
2504
(errmsg("received immediate shutdown request")));
2463
- SignalChildren(SIGQUIT);
2464
- if (StartupPID != 0)
2465
- signal_child(StartupPID, SIGQUIT);
2466
- if (BgWriterPID != 0)
2467
- signal_child(BgWriterPID, SIGQUIT);
2468
- if (CheckpointerPID != 0)
2469
- signal_child(CheckpointerPID, SIGQUIT);
2470
- if (WalWriterPID != 0)
2471
- signal_child(WalWriterPID, SIGQUIT);
2472
- if (WalReceiverPID != 0)
2473
- signal_child(WalReceiverPID, SIGQUIT);
2474
- if (AutoVacPID != 0)
2475
- signal_child(AutoVacPID, SIGQUIT);
2476
- if (PgArchPID != 0)
2477
- signal_child(PgArchPID, SIGQUIT);
2478
- if (PgStatPID != 0)
2479
- signal_child(PgStatPID, SIGQUIT);
2480
- SignalUnconnectedWorkers(SIGQUIT);
2481
- ExitPostmaster(0);
2505
+
2506
+ TerminateChildren(SIGQUIT);
2507
+ pmState = PM_WAIT_BACKENDS;
2508
+
2509
+ /* set stopwatch for them to die */
2510
+ AbortStartTime = time(NULL);
2511
+
2512
+ /*
2513
+ * Now wait for backends to exit. If there are none,
2514
+ * PostmasterStateMachine will take the next step.
2515
+ */
2516
+ PostmasterStateMachine();
2482
2517
break;
2483
2518
}
2484
2519
@@ -2952,12 +2987,17 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
2952
2987
dlist_mutable_iter iter;
2953
2988
slist_iter siter;
2954
2989
Backend *bp;
2990
+ bool take_action;
2955
2991
2956
2992
/*
2957
- * Make log entry unless there was a previous crash (if so, nonzero exit
2958
- * status is to be expected in SIGQUIT response; don't clutter log)
2993
+ * We only log messages and send signals if this is the first process crash
2994
+ * and we're not doing an immediate shutdown; otherwise, we're only here to
2995
+ * update postmaster's idea of live processes. If we have already signalled
2996
+ * children, nonzero exit status is to be expected, so don't clutter log.
2959
2997
*/
2960
- if (!FatalError)
2998
+ take_action = !FatalError && Shutdown != ImmediateShutdown;
2999
+
3000
+ if (take_action)
2961
3001
{
2962
3002
LogChildExit(LOG, procname, pid, exitstatus);
2963
3003
ereport(LOG,
@@ -3003,7 +3043,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3003
3043
* (-s on command line), then we send SIGSTOP instead, so that we
3004
3044
* can get core dumps from all backends by hand.
3005
3045
*/
3006
- if (!FatalError )
3046
+ if (take_action )
3007
3047
{
3008
3048
ereport(DEBUG2,
3009
3049
(errmsg_internal("sending %s to process %d",
@@ -3055,7 +3095,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3055
3095
if (bp->bkend_type == BACKEND_TYPE_BGWORKER)
3056
3096
continue;
3057
3097
3058
- if (!FatalError )
3098
+ if (take_action )
3059
3099
{
3060
3100
ereport(DEBUG2,
3061
3101
(errmsg_internal("sending %s to process %d",
@@ -3069,7 +3109,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3069
3109
/* Take care of the startup process too */
3070
3110
if (pid == StartupPID)
3071
3111
StartupPID = 0;
3072
- else if (StartupPID != 0 && !FatalError )
3112
+ else if (StartupPID != 0 && take_action )
3073
3113
{
3074
3114
ereport(DEBUG2,
3075
3115
(errmsg_internal("sending %s to process %d",
@@ -3081,7 +3121,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3081
3121
/* Take care of the bgwriter too */
3082
3122
if (pid == BgWriterPID)
3083
3123
BgWriterPID = 0;
3084
- else if (BgWriterPID != 0 && !FatalError )
3124
+ else if (BgWriterPID != 0 && take_action )
3085
3125
{
3086
3126
ereport(DEBUG2,
3087
3127
(errmsg_internal("sending %s to process %d",
@@ -3093,7 +3133,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3093
3133
/* Take care of the checkpointer too */
3094
3134
if (pid == CheckpointerPID)
3095
3135
CheckpointerPID = 0;
3096
- else if (CheckpointerPID != 0 && !FatalError )
3136
+ else if (CheckpointerPID != 0 && take_action )
3097
3137
{
3098
3138
ereport(DEBUG2,
3099
3139
(errmsg_internal("sending %s to process %d",
@@ -3105,7 +3145,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3105
3145
/* Take care of the walwriter too */
3106
3146
if (pid == WalWriterPID)
3107
3147
WalWriterPID = 0;
3108
- else if (WalWriterPID != 0 && !FatalError )
3148
+ else if (WalWriterPID != 0 && take_action )
3109
3149
{
3110
3150
ereport(DEBUG2,
3111
3151
(errmsg_internal("sending %s to process %d",
@@ -3117,7 +3157,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3117
3157
/* Take care of the walreceiver too */
3118
3158
if (pid == WalReceiverPID)
3119
3159
WalReceiverPID = 0;
3120
- else if (WalReceiverPID != 0 && !FatalError )
3160
+ else if (WalReceiverPID != 0 && take_action )
3121
3161
{
3122
3162
ereport(DEBUG2,
3123
3163
(errmsg_internal("sending %s to process %d",
@@ -3129,7 +3169,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3129
3169
/* Take care of the autovacuum launcher too */
3130
3170
if (pid == AutoVacPID)
3131
3171
AutoVacPID = 0;
3132
- else if (AutoVacPID != 0 && !FatalError )
3172
+ else if (AutoVacPID != 0 && take_action )
3133
3173
{
3134
3174
ereport(DEBUG2,
3135
3175
(errmsg_internal("sending %s to process %d",
@@ -3144,7 +3184,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3144
3184
* simplifies the state-machine logic in the case where a shutdown request
3145
3185
* arrives during crash processing.)
3146
3186
*/
3147
- if (PgArchPID != 0 && !FatalError )
3187
+ if (PgArchPID != 0 && take_action )
3148
3188
{
3149
3189
ereport(DEBUG2,
3150
3190
(errmsg_internal("sending %s to process %d",
@@ -3159,7 +3199,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3159
3199
* simplifies the state-machine logic in the case where a shutdown request
3160
3200
* arrives during crash processing.)
3161
3201
*/
3162
- if (PgStatPID != 0 && !FatalError )
3202
+ if (PgStatPID != 0 && take_action )
3163
3203
{
3164
3204
ereport(DEBUG2,
3165
3205
(errmsg_internal("sending %s to process %d",
@@ -3171,7 +3211,9 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3171
3211
3172
3212
/* We do NOT restart the syslogger */
3173
3213
3174
- FatalError = true;
3214
+ if (Shutdown != ImmediateShutdown)
3215
+ FatalError = true;
3216
+
3175
3217
/* We now transit into a state of waiting for children to die */
3176
3218
if (pmState == PM_RECOVERY ||
3177
3219
pmState == PM_HOT_STANDBY ||
@@ -3180,6 +3222,13 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
3180
3222
pmState == PM_WAIT_READONLY ||
3181
3223
pmState == PM_SHUTDOWN)
3182
3224
pmState = PM_WAIT_BACKENDS;
3225
+
3226
+ /*
3227
+ * .. and if this doesn't happen quickly enough, now the clock is ticking
3228
+ * for us to kill them without mercy.
3229
+ */
3230
+ if (AbortStartTime == 0)
3231
+ AbortStartTime = time(NULL);
3183
3232
}
3184
3233
3185
3234
/*
@@ -3316,7 +3365,7 @@ PostmasterStateMachine(void)
3316
3365
WalWriterPID == 0 &&
3317
3366
AutoVacPID == 0)
3318
3367
{
3319
- if (FatalError)
3368
+ if (Shutdown >= ImmediateShutdown || FatalError)
3320
3369
{
3321
3370
/*
3322
3371
* Start waiting for dead_end children to die. This state
@@ -3326,7 +3375,8 @@ PostmasterStateMachine(void)
3326
3375
3327
3376
/*
3328
3377
* We already SIGQUIT'd the archiver and stats processes, if
3329
- * any, when we entered FatalError state.
3378
+ * any, when we started immediate shutdown or entered
3379
+ * FatalError state.
3330
3380
*/
3331
3381
}
3332
3382
else
@@ -3511,6 +3561,7 @@ signal_child(pid_t pid, int signal)
3511
3561
case SIGTERM:
3512
3562
case SIGQUIT:
3513
3563
case SIGSTOP:
3564
+ case SIGKILL:
3514
3565
if (kill(-pid, signal) < 0)
3515
3566
elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) (-pid), signal);
3516
3567
break;
@@ -3597,6 +3648,33 @@ SignalSomeChildren(int signal, int target)
3597
3648
return signaled;
3598
3649
}
3599
3650
3651
+ /*
3652
+ * Send a termination signal to children. This considers all of our children
3653
+ * processes, except syslogger and dead_end backends.
3654
+ */
3655
+ static void
3656
+ TerminateChildren(int signal)
3657
+ {
3658
+ SignalChildren(signal);
3659
+ if (StartupPID != 0)
3660
+ signal_child(StartupPID, signal);
3661
+ if (BgWriterPID != 0)
3662
+ signal_child(BgWriterPID, signal);
3663
+ if (CheckpointerPID != 0)
3664
+ signal_child(CheckpointerPID, signal);
3665
+ if (WalWriterPID != 0)
3666
+ signal_child(WalWriterPID, signal);
3667
+ if (WalReceiverPID != 0)
3668
+ signal_child(WalReceiverPID, signal);
3669
+ if (AutoVacPID != 0)
3670
+ signal_child(AutoVacPID, signal);
3671
+ if (PgArchPID != 0)
3672
+ signal_child(PgArchPID, signal);
3673
+ if (PgStatPID != 0)
3674
+ signal_child(PgStatPID, signal);
3675
+ SignalUnconnectedWorkers(signal);
3676
+ }
3677
+
3600
3678
/*
3601
3679
* BackendStartup -- start backend process
3602
3680
*
0 commit comments