@@ -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