From 7ffe72acb5913c9de35e2553ab5f5a4f0ad659bb Mon Sep 17 00:00:00 2001 From: liuchun Date: Thu, 24 Feb 2022 14:11:25 +0800 Subject: [PATCH] =?UTF-8?q?notify=20=E6=94=AF=E6=8C=81=E6=8C=87=E5=AE=9Aca?= =?UTF-8?q?scade=20standby?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bin/pg_ctl/pg_ctl.cpp | 9 ++++++ .../process/postmaster/postmaster.cpp | 29 ++++++++++++++++++- .../process/postmaster/startup.cpp | 2 ++ .../storage/access/transam/xlog.cpp | 19 ++++++++++++ src/include/access/xlog.h | 1 + src/include/postmaster/startup.h | 4 +-- 6 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/bin/pg_ctl/pg_ctl.cpp b/src/bin/pg_ctl/pg_ctl.cpp index 49d0fc0f..89771c1c 100644 --- a/src/bin/pg_ctl/pg_ctl.cpp +++ b/src/bin/pg_ctl/pg_ctl.cpp @@ -171,6 +171,7 @@ static char switchover_file[MAXPGPATH]; static char promote_file[MAXPGPATH]; static char primary_file[MAXPGPATH]; static char standby_file[MAXPGPATH]; +static char cascade_standby_file[MAXPGPATH]; static char pg_ctl_lockfile[MAXPGPATH]; static char pg_conf_file[MAXPGPATH]; static FILE* lockfile = NULL; @@ -2147,6 +2148,10 @@ static void do_notify(uint32 term) pgha_str[strlen("primary")] == '\0') { notify_file = xstrdup(primary_file); notify_mode = PRIMARY_MODE; + } else if ((pgha_str != NULL) && 0 == strncmp(pgha_str, "cascade_standby", strlen("cascade_standby")) && + pgha_str[strlen("cascade_standby")] == '\0') { + notify_file = xstrdup(cascade_standby_file); + notify_mode = CASCADE_STANDBY_MODE; } else { pg_log(PG_WARNING, _(" the parameter of notify is not recognized\n")); exit(1); @@ -3786,6 +3791,8 @@ static char* get_localrole_string(ServerMode mode) return "Primary"; case STANDBY_MODE: return "Standby"; + case CASCADE_STANDBY_MODE: + return "Cascade Standby"; case PENDING_MODE: return "Pending"; default: @@ -5099,6 +5106,8 @@ int main(int argc, char** argv) securec_check_ss_c(ret, "\0", "\0"); ret = snprintf_s(standby_file, MAXPGPATH, MAXPGPATH - 1, "%s/standby", pg_data); securec_check_ss_c(ret, "\0", "\0"); + ret = snprintf_s(cascade_standby_file, MAXPGPATH, MAXPGPATH - 1, "%s/cascade_standby", pg_data); + securec_check_ss_c(ret, "\0", "\0"); ret = snprintf_s(pg_ctl_lockfile, MAXPGPATH, MAXPGPATH - 1, "%s/pg_ctl.lock", pg_data); securec_check_ss_c(ret, "\0", "\0"); ret = snprintf_s(pg_conf_file, MAXPGPATH, MAXPGPATH - 1, "%s/postgresql.conf", pg_data); diff --git a/src/gausskernel/process/postmaster/postmaster.cpp b/src/gausskernel/process/postmaster/postmaster.cpp index b4d37443..98e9a8e0 100755 --- a/src/gausskernel/process/postmaster/postmaster.cpp +++ b/src/gausskernel/process/postmaster/postmaster.cpp @@ -1,4 +1,4 @@ -/* ------------------------------------------------------------------------- +/* ------------------------------------------------------------------------- * * postmaster.cpp * This program acts as a clearing house for requests to the @@ -4923,6 +4923,7 @@ static void reaper(SIGNAL_ARGS) if (g_instance.demotion > NoDemote && t_thrd.postmaster_cxt.HaShmData->current_mode == STANDBY_MODE && (EXIT_STATUS_0(exitstatus) || EXIT_STATUS_1(exitstatus))) { + pmState = PM_WAIT_BACKENDS; continue; } @@ -7197,6 +7198,27 @@ static void handle_standby_signal(volatile HaShmemData* hashmdata) } } +static void handle_cascade_standby_signal(volatile HaShmemData* hashmdata) +{ + if (g_instance.pid_cxt.StartupPID != 0 && + (pmState == PM_STARTUP || + pmState == PM_RECOVERY || + pmState == PM_HOT_STANDBY || + pmState == PM_WAIT_READONLY)) { + hashmdata->current_mode = STANDBY_MODE; + hashmdata->is_cascade_standby = true; + PMUpdateDBState(NEEDREPAIR_STATE, get_cur_mode(), get_cur_repl_num()); + ereport(LOG, + (errmsg("update gaussdb state file: db state(NEEDREPAIR_STATE), server mode(%s)", + wal_get_role_string(get_cur_mode())))); + /* + * wakeup startup process from sleep by signal, cause we are + * in standby mode, the signal has no specific affect. + */ + SendNotifySignal(NOTIFY_CASCADE_STANDBY, g_instance.pid_cxt.StartupPID); + UpdateOptsFile(); + } +} /* * sigusr1_handler - handle signal conditions from child processes */ @@ -7375,6 +7397,11 @@ static void sigusr1_handler(SIGNAL_ARGS) handle_standby_signal(hashmdata); } + /* If it is cascade standby signal, then set HaShmData and send sigusr2 to startup process */ + if (CheckCascadeStandbySignal()) { + handle_cascade_standby_signal(hashmdata); + } + if (CheckPostmasterSignal(PMSIGNAL_UPDATE_NORMAL)) { PMUpdateDBState(NORMAL_STATE, get_cur_mode(), get_cur_repl_num()); ereport(LOG, diff --git a/src/gausskernel/process/postmaster/startup.cpp b/src/gausskernel/process/postmaster/startup.cpp index e4989782..f4047b9b 100644 --- a/src/gausskernel/process/postmaster/startup.cpp +++ b/src/gausskernel/process/postmaster/startup.cpp @@ -109,6 +109,8 @@ static void StartupProcSigusr2Handler(SIGNAL_ARGS) t_thrd.startup_cxt.primary_triggered = true; } else if (CheckNotifySignal(NOTIFY_STANDBY)) { t_thrd.startup_cxt.standby_triggered = true; + } else if (CheckNotifySignal(NOTIFY_CASCADE_STANDBY)) { + t_thrd.startup_cxt.standby_triggered = true; } else if (CheckNotifySignal(NOTIFY_FAILOVER)) { t_thrd.startup_cxt.failover_triggered = true; WakeupRecovery(); diff --git a/src/gausskernel/storage/access/transam/xlog.cpp b/src/gausskernel/storage/access/transam/xlog.cpp index bad6cdb3..b7317f69 100644 --- a/src/gausskernel/storage/access/transam/xlog.cpp +++ b/src/gausskernel/storage/access/transam/xlog.cpp @@ -144,6 +144,7 @@ #define SWITCHOVER_SIGNAL_FILE "switchover" #define PRIMARY_SIGNAL_FILE "primary" #define STANDBY_SIGNAL_FILE "standby" +#define CASCADE_STANDBY_SIGNAL_FILE "cascade_standby" #define XLOG_SWITCH_HISTORY_FILE "switch.history" #define MAX_PATH_LEN 1024 #define MAX(A, B) ((B) > (A) ? (B) : (A)) @@ -16755,6 +16756,24 @@ bool CheckStandbySignal(void) return false; } +/* + * Check whether the signal is cascade standby signal + */ +bool CheckCascadeStandbySignal(void) +{ + struct stat stat_buf; + + if (stat(CASCADE_STANDBY_SIGNAL_FILE, &stat_buf) == 0) { + /* + * Since we are in a signal handler, it's not safe to elog. We + * silently ignore any error from unlink. + */ + (void)unlink(CASCADE_STANDBY_SIGNAL_FILE); + return true; + } + return false; +} + /* * Check to see if a switchover request has arrived and * read demote mode from switchover signal file. diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 2a7f1fd5..7766d646 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -389,6 +389,7 @@ extern bool CheckFinishRedoSignal(void); extern bool CheckPromoteSignal(void); extern bool CheckPrimarySignal(void); extern bool CheckStandbySignal(void); +extern bool CheckCascadeStandbySignal(void); extern bool CheckNormalSignal(void); extern int CheckSwitchoverSignal(void); diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h index 28bc8b40..1320cd1b 100644 --- a/src/include/postmaster/startup.h +++ b/src/include/postmaster/startup.h @@ -12,8 +12,8 @@ #ifndef _STARTUP_H #define _STARTUP_H -typedef enum { NOTIFY_PRIMARY = 0, NOTIFY_STANDBY, NOTIFY_FAILOVER, NOTIFY_SWITCHOVER, NUM_NOTIFYS } NotifyReason; - +typedef enum { NOTIFY_PRIMARY = 0, NOTIFY_STANDBY, NOTIFY_CASCADE_STANDBY, NOTIFY_FAILOVER, + NOTIFY_SWITCHOVER, NUM_NOTIFYS } NotifyReason; /* * Save the notify signal reason in the share memory. * NotifySignalFlags include primary signal, standby signal and promote signal.