From c40439b252a500544adf794bfdbfb15a86e34623 Mon Sep 17 00:00:00 2001 From: chenzhikai <895543892@qq.com> Date: Thu, 13 Mar 2025 21:10:31 +0800 Subject: [PATCH] =?UTF-8?q?pg=5Fcontroldata=E6=94=AF=E6=8C=81=E5=8D=87?= =?UTF-8?q?=E7=BA=A7reform=20ctrl=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bin/pg_controldata/pg_controldata.cpp | 89 ++++++++++++++++++- .../ddes/adapter/ss_dms_recovery.cpp | 1 + src/include/ddes/dms/ss_dms_recovery.h | 19 +++- 3 files changed, 104 insertions(+), 5 deletions(-) diff --git a/src/bin/pg_controldata/pg_controldata.cpp b/src/bin/pg_controldata/pg_controldata.cpp index 2a8fcd975a..72a1cac7b7 100644 --- a/src/bin/pg_controldata/pg_controldata.cpp +++ b/src/bin/pg_controldata/pg_controldata.cpp @@ -48,6 +48,8 @@ static void usage(const char* prog_name) printf(_(" --enable-dss enable shared storage mode\n")); printf(_(" --socketpath=SOCKETPATH\n")); printf(_(" dss connect socket file path\n")); + printf(_(" --update-ctrl\n")); + printf(_(" update pg_control ctrl page in shared storage mode\n")); #endif printf(_(" -V, --version output version information, then exit\n")); printf(_(" -?, --help show this help, then exit\n")); @@ -135,6 +137,76 @@ static void exit_safely(int returnCode) exit(returnCode); } +void SSCheckAndUpdateReformerCtrl(const char* ControlFilePath) +{ + printf(_("pg_control ctrl page update start\n")); + int fd = -1; + int len_v1 = sizeof(ss_reformer_ctrl_v1_t); + int len_v2 = sizeof(ss_reformer_ctrl_t); + char buffer_v1[BUFFERALIGN(len_v1)] __attribute__((__aligned__(ALIGNOF_BUFFER))) = { 0 }; + char buffer_v2[BUFFERALIGN(len_v2)] __attribute__((__aligned__(ALIGNOF_BUFFER))) = { 0 }; + errno_t err = EOK; + + fd = open(ControlFilePath, O_RDONLY | PG_BINARY, S_IRUSR | S_IWUSR); + if (fd < 0) { + fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), progname, ControlFilePath, strerror(errno)); + exit_safely(2); + } + off_t seekpos = (off_t)BLCKSZ * (MAX_INSTANCEID + 1); + if (lseek(fd, (off_t)seekpos, SEEK_SET) < 0) { + fprintf(stderr, _("%s: could not seek in \"%s\" to offset %d: %s\n"), + progname, ControlFilePath, seekpos, strerror(errno)); + close(fd); + exit_safely(2); + } + + if (read(fd, buffer_v1, len_v1) != len_v1) { + fprintf(stderr, _("%s: could not read file \"%s\": %s\n"), progname, ControlFilePath, strerror(errno)); + exit_safely(2); + } + (void)close(fd); + + ss_reformer_ctrl_v1_t *ctrl_v1 = (ss_reformer_ctrl_v1_t *)buffer_v1; + if (ctrl_v1->version == REFORM_CTRL_V1_VERSION) { + ss_reformer_ctrl_t *ctrl_v2 = (ss_reformer_ctrl_t *)buffer_v2; + ctrl_v2->version = REFORM_CTRL_VERSION; + ctrl_v2->list_stable = ctrl_v1->list_stable; + ctrl_v2->primaryInstId = ctrl_v1->primaryInstId; + ctrl_v2->recoveryInstId = ctrl_v1->recoveryInstId; + ctrl_v2->clusterStatus = ctrl_v1->clusterStatus; + ctrl_v2->clusterRunMode = ctrl_v1->clusterRunMode; + ctrl_v2->exrto_list_stable = 0; + err = memset_s(ctrl_v2->reserved, sizeof(ctrl_v2->reserved), 0, sizeof(ctrl_v2->reserved)); + securec_check(err, "\0", "\0"); + + INIT_CRC32C(ctrl_v2->crc); + COMP_CRC32C(ctrl_v2->crc, (char *)ctrl_v2, offsetof(ss_reformer_ctrl_t, crc)); + FIN_CRC32C(ctrl_v2->crc); + + fd = open(ControlFilePath, O_WRONLY | PG_BINARY, S_IRUSR | S_IWUSR); + if (fd < 0) { + fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), progname, ControlFilePath, strerror(errno)); + exit_safely(2); + } + + if (lseek(fd, (off_t)seekpos, SEEK_SET) < 0) { + fprintf(stderr, _("%s: could not seek in \"%s\" to offset %d: %s\n"), + progname, ControlFilePath, seekpos, strerror(errno)); + close(fd); + exit_safely(2); + } + + if (write(fd, buffer_v2, len_v2) != len_v2) { + fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), progname, ControlFilePath, strerror(errno)); + exit_safely(2); + } + (void)close(fd); + printf(_("pg_control ctrl page update success\n")); + } else { + printf(_("pg_control ctrl page not need to update\n")); + } +} + static void display_control_page(ControlFileData ControlFile, int instance_id, bool display_all) { pg_crc32c crc; /* pg_crc32c as same as pg_crc32 */ @@ -294,6 +366,7 @@ int main(int argc, char* argv[]) ControlFileData ControlFile; int fd = -1; bool display_all = true; + bool is_update_ctrl = false; char ControlFilePath[MAXPGPATH]; char* DataDir = NULL; char* socketpath = NULL; @@ -305,8 +378,10 @@ int main(int argc, char* argv[]) const int SS_NODEID = MIN_INSTANCEID; off_t ControlFileSize; - static struct option long_options[] = {{"enable-dss", no_argument, NULL, 1}, + static struct option long_options[] = { + {"enable-dss", no_argument, NULL, 1}, {"socketpath", required_argument, NULL, 2}, + {"update-ctrl", no_argument, NULL, 3}, {NULL, 0, NULL, 0}}; set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata")); @@ -338,6 +413,9 @@ int main(int argc, char* argv[]) enable_dss = true; socketpath = strdup(optarg); break; + case 3: + is_update_ctrl = true; + break; #endif default: /* getopt_long already emitted a complaint */ @@ -387,6 +465,11 @@ int main(int argc, char* argv[]) } securec_check_ss_c(sret, "\0", "\0"); + if (is_update_ctrl && enable_dss) { + SSCheckAndUpdateReformerCtrl(ControlFilePath); + exit_safely(0); + } + fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0); if (fd < 0) { fprintf( @@ -399,7 +482,7 @@ int main(int argc, char* argv[]) close(fd); exit_safely(2); } - + display_id = SS_NODEID; seekpos = (int)BLCKSZ * SS_NODEID; if (seekpos >= ControlFileSize) { @@ -408,7 +491,7 @@ int main(int argc, char* argv[]) close(fd); exit_safely(2); } - + do { if (lseek(fd, (off_t)seekpos, SEEK_SET) < 0) { fprintf(stderr, _("%s: could not seek in \"%s\" to offset %d: %s\n"), diff --git a/src/gausskernel/ddes/adapter/ss_dms_recovery.cpp b/src/gausskernel/ddes/adapter/ss_dms_recovery.cpp index a5c5bc0157..5f56d815b8 100644 --- a/src/gausskernel/ddes/adapter/ss_dms_recovery.cpp +++ b/src/gausskernel/ddes/adapter/ss_dms_recovery.cpp @@ -153,6 +153,7 @@ bool SSRecoveryApplyDelay() /* initialize reformer ctrl parameter when initdb */ void SSInitReformerControlPages(void) { + static_assert(sizeof(ss_reformer_ctrl_t) == REFORM_CTRL_SIZE, "ss_reformer_ctrl_t size is not 1024 bytes"); /* * If already exists control file, reformer page must have been initialized */ diff --git a/src/include/ddes/dms/ss_dms_recovery.h b/src/include/ddes/dms/ss_dms_recovery.h index d8ab826ec3..f369911b1a 100644 --- a/src/include/ddes/dms/ss_dms_recovery.h +++ b/src/include/ddes/dms/ss_dms_recovery.h @@ -67,15 +67,30 @@ SS_NORMAL_PRIMARY && g_instance.dms_cxt.SSRecoveryInfo.realtimeBuildLogCtrlStatus > DISABLE) #define SS_STANDBY_ENABLE_TARGET_RTO (SS_NORMAL_STANDBY && \ SS_ONDEMAND_REALTIME_BUILD_NORMAL && g_instance.dms_cxt.SSRecoveryInfo.realtimeBuildLogCtrlStatus > DISABLE) -#define REFORM_CTRL_VERSION 1 -typedef struct st_reformer_ctrl { +#define REFORM_CTRL_V1_VERSION 1 +#define REFORM_CTRL_VERSION 2 +#define REFORM_CTRL_SIZE (1024) +#define REFORM_CTRL_RESERVED_SIZE (1024 - 48) + +typedef struct st_reformer_ctrl_v1 { uint32 version; uint64 list_stable; // stable instances list int primaryInstId; int recoveryInstId; // abandoned in xlog merge SSGlobalClusterState clusterStatus; ClusterRunMode clusterRunMode; + pg_crc32c crc; +} ss_reformer_ctrl_v1_t; + +typedef struct st_reformer_ctrl { + uint32 version; + uint64 list_stable; // stable instances list + int32 primaryInstId; + int32 recoveryInstId; // abandoned in xlog merge + SSGlobalClusterState clusterStatus; + ClusterRunMode clusterRunMode; uint64 exrto_list_stable; // exrto stable instances list for ss_disaster_cluster + char reserved[REFORM_CTRL_RESERVED_SIZE]; pg_crc32c crc; } ss_reformer_ctrl_t; -- Gitee