From b26a2631e66dccdb822ecbcfef88b940e97898ec Mon Sep 17 00:00:00 2001 From: "suyu.cmj" Date: Fri, 3 Sep 2021 12:11:50 +0800 Subject: [PATCH] Add guc parameter to enable send SIGSTOP to peers when backend exits abnormally --- src/backend/postmaster/postmaster.c | 25 ++++++++++++++++++++++--- src/backend/utils/misc/guc.c | 18 ++++++++++++++++++ src/include/postmaster/postmaster.h | 1 + src/include/utils/guc.h | 2 ++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 9c2c98614a..183c16606f 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -223,7 +223,7 @@ static pgsocket ListenSocket[MAXLISTEN]; /* * These globals control the behavior of the postmaster in case some * backend dumps core. Normally, it kills all peers of the dead backend - * and reinitializes shared memory. By specifying -s or -n, we can have + * and reinitializes shared memory. By specifying -T or -n, we can have * the postmaster stop (rather than kill) peers and not reinitialize * shared data structures. (Reinit is currently dead code, though.) */ @@ -816,6 +816,12 @@ PostmasterMain(int argc, char *argv[]) * post_hacker collect core dumps from everyone. */ SendStop = true; + /* + * set guc parameter enable_send_stop at the same time when specified -T on command line. + * avoid the value of SendStop being reset by enable_send_stop in postgresql.conf + * the priority of setting guc parameter by command line is higher than that by postgresql.conf + */ + SetConfigOption("enable_send_stop", "true", PGC_POSTMASTER, PGC_S_ARGV); break; case 't': @@ -3501,7 +3507,8 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) * * SIGQUIT is the special signal that says exit without proc_exit * and let the user know what's going on. But if SendStop is set - * (-T on command line), then we send SIGSTOP instead, so that we + * (-T on command line or set guc parameter enable_send_stop), + * then we send SIGSTOP instead, so that we * can get core dumps from all backends by hand. */ if (take_action) @@ -3544,7 +3551,8 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) * * SIGQUIT is the special signal that says exit without proc_exit * and let the user know what's going on. But if SendStop is set - * (-T on command line), then we send SIGSTOP instead, so that we + * (-T on command line or set guc parameter enable_send_stop), + * then we send SIGSTOP instead, so that we * can get core dumps from all backends by hand. * * We could exclude dead_end children here, but at least in the @@ -6616,3 +6624,14 @@ InitPostmasterDeathWatchHandle(void) GetLastError()))); #endif /* WIN32 */ } + + +/* + * set value of SendStop according to guc parameter enable_send_stop + * so that it can be set not only by specifying -T when start postgres + */ +void +assign_enable_send_stop(bool newval, void *extra) +{ + SendStop = newval; +} \ No newline at end of file diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 29851119f1..a6ca8511b4 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -584,6 +584,7 @@ char *event_source; bool row_security; bool check_function_bodies = true; +bool enable_send_stop = false; /* * This GUC exists solely for backward compatibility, check its definition for @@ -2116,6 +2117,23 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + /* + * In the event that some backend dumps core, send SIGSTOP rather than SIGQUIT + * to all its peers, this lets the wily post_hacker collect core dumps from everyone. + * in original way, this is set with -T parameter when start postgres + * changes to set via guc parameter enable_send_stop + */ + { + {"enable_send_stop", PGC_SIGHUP, UNGROUPED, + gettext_noop("Enable to send SIGSTOP to all peers when some backend exit abnormally"), + NULL, + GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL + }, + &enable_send_stop, + false, + NULL, assign_enable_send_stop, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h index 0efdd7c232..77056f7a6e 100644 --- a/src/include/postmaster/postmaster.h +++ b/src/include/postmaster/postmaster.h @@ -54,6 +54,7 @@ extern void InitProcessGlobals(void); extern int MaxLivePostmasterChildren(void); extern bool PostmasterMarkPIDForWorkerNotify(int); +extern void assign_enable_send_stop(bool newval, void *extra); #ifdef EXEC_BACKEND extern pid_t postmaster_forkexec(int argc, char *argv[]); diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index a7c3a4958e..feec65cb16 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -282,6 +282,8 @@ extern int tcp_user_timeout; extern bool trace_sort; #endif +extern bool enable_send_stop; + /* * Functions exported by guc.c */ -- 2.24.3 (Apple Git-128)