From 9a836b3c046985c11ffc8a68bd9981dd478d4161 Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Thu, 3 Sep 2020 10:40:17 +0900 Subject: [PATCH] Add option --verify-backup This causes pg_verifybackup to be executed immediately after pg_basebackup completes. PostreSQL 13 and later. --- HISTORY | 1 + doc/repmgr-standby-clone.xml | 17 +++++++++ repmgr-action-standby.c | 71 +++++++++++++++++++++++++++++++++++- repmgr-client-global.h | 3 +- repmgr-client.c | 4 ++ repmgr-client.h | 2 + 6 files changed, 96 insertions(+), 2 deletions(-) diff --git a/HISTORY b/HISTORY index 1dc8c23d..f5beb371 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,7 @@ 5.2.0 2020-??-?? repmgr: improve database connection failure error checking on the demotion candidate during "standby switchover" (Ian) + repmgr: add option --verify-backup to "standby clone" 5.1.0 2020-04-13 repmgr: remove BDR 2.x support diff --git a/doc/repmgr-standby-clone.xml b/doc/repmgr-standby-clone.xml index 7e0104e3..06e40384 100644 --- a/doc/repmgr-standby-clone.xml +++ b/doc/repmgr-standby-clone.xml @@ -373,6 +373,23 @@ + + + + + + + Verify a cloned node using the + pg_verifybackup + utility (PostgreSQL 13 and later). + + + This option can currently only be used when cloning directly from an upstream + node. + + + + diff --git a/repmgr-action-standby.c b/repmgr-action-standby.c index a9101c64..4f789578 100644 --- a/repmgr-action-standby.c +++ b/repmgr-action-standby.c @@ -157,6 +157,7 @@ static CheckStatus parse_db_connection(const char *db_connection); * --replication-user (only required if no upstream record) * --without-barman * --replication-conf-only (--recovery-conf-only) + * --verify-backup (PostgreSQL 13 and later) */ void @@ -218,6 +219,15 @@ do_standby_clone(void) if (mode == barman) { + /* + * Not currently possible to use --verify-backup with Barman + */ + if (runtime_options.verify_backup == true) + { + log_error(_("--verify-backup option cannot be used when cloning from Barman backups")); + exit(ERR_BAD_CONFIG); + } + /* * Sanity-check barman connection and installation; * this will exit with ERR_BARMAN if problems found. @@ -323,13 +333,25 @@ do_standby_clone(void) /* * This connects to the source node and performs sanity checks, also * sets "recovery_conninfo_str", "upstream_repluser", "upstream_user" and - * "upstream_node_id". + * "upstream_node_id" and creates a connection handle in "source_conn". * * Will error out if source connection not possible and not in * "barman" mode. */ check_source_server(); + if (runtime_options.verify_backup == true) + { + /* + * --verify-backup available for PostgreSQL 13 and later + */ + if (PQserverVersion(source_conn) < 130000) + { + log_error(_("--verify-backup available for PostgreSQL 13 and later")); + exit(ERR_BAD_CONFIG); + } + } + /* attempt to retrieve upstream node record */ record_status = get_node_record(source_conn, upstream_node_id, @@ -341,6 +363,7 @@ do_standby_clone(void) upstream_node_id); exit(ERR_BAD_CONFIG); } + } else { @@ -719,6 +742,49 @@ do_standby_clone(void) exit(r); } + /* + * Run pg_verifybackup here if requested, before any alterations are made + * to the data directory. + */ + if (mode == pg_basebackup && runtime_options.verify_backup == true) + { + PQExpBufferData command; + int r; + struct stat st; + + initPQExpBuffer(&command); + + make_pg_path(&command, "pg_verifybackup"); + + /* check command actually exists */ + if (stat(command.data, &st) != 0) + { + log_error(_("unable to find expected binary \"%s\""), command.data); + log_detail("%s", strerror(errno)); + exit(ERR_BAD_CONFIG); + } + + appendPQExpBufferStr(&command, " "); + + /* Somewhat inconsistent, but pg_verifybackup doesn't accept a -D option */ + appendShellString(&command, + local_data_directory); + + log_debug("executing:\n %s", command.data); + + r = system(command.data); + termPQExpBuffer(&command); + + if (r != 0) + { + log_error(_("unable to verify backup")); + exit(ERR_BAD_BASEBACKUP); + } + + log_verbose(LOG_INFO, _("backup successfully verified")); + + } + /* * If `--copy-external-config-files` was provided, copy any configuration @@ -8841,6 +8907,9 @@ do_standby_help(void) printf(_(" --upstream-conninfo \"primary_conninfo\" value to write in recovery.conf\n" \ " when the intended upstream server does not yet exist\n")); printf(_(" --upstream-node-id ID of the upstream node to replicate from (optional, defaults to primary node)\n")); +#if (PG_VERSION_NUM >= 130000) + printf(_(" --verify-backup verify a cloned node using the \"pg_verifybackup\" utility\n")); +#endif printf(_(" --without-barman do not use Barman even if configured\n")); printf(_(" --replication-conf-only generate replication configuration for a previously cloned instance\n")); diff --git a/repmgr-client-global.h b/repmgr-client-global.h index d113d7cb..0d59f917 100644 --- a/repmgr-client-global.h +++ b/repmgr-client-global.h @@ -88,6 +88,7 @@ typedef struct char upstream_conninfo[MAXLEN]; bool without_barman; bool replication_conf_only; + bool verify_backup; /* "standby clone"/"standby follow" options */ int upstream_node_id; @@ -163,7 +164,7 @@ typedef struct UNKNOWN_NODE_ID, "", "", UNKNOWN_NODE_ID, \ /* "standby clone" options */ \ false, CONFIG_FILE_SAMEPATH, false, false, false, "", "", "", \ - false, false, \ + false, false, false, \ /* "standby clone"/"standby follow" options */ \ NO_UPSTREAM_NODE, \ /* "standby register" options */ \ diff --git a/repmgr-client.c b/repmgr-client.c index b4f89655..344ed67d 100644 --- a/repmgr-client.c +++ b/repmgr-client.c @@ -433,6 +433,10 @@ main(int argc, char **argv) runtime_options.replication_conf_only = true; break; + /* --verify-backup */ + case OPT_VERIFY_BACKUP: + runtime_options.verify_backup = true; + break; /*--------------------------- * "standby register" options diff --git a/repmgr-client.h b/repmgr-client.h index 03defa7d..d0ff820a 100644 --- a/repmgr-client.h +++ b/repmgr-client.h @@ -98,6 +98,7 @@ #define OPT_REPMGRD_FORCE_UNPAUSE 1045 #define OPT_REPLICATION_CONFIG_OWNER 1046 #define OPT_DB_CONNECTION 1047 +#define OPT_VERIFY_BACKUP 1048 /* These options are for internal use only */ #define OPT_CONFIG_ARCHIVE_DIR 2001 @@ -160,6 +161,7 @@ static struct option long_options[] = {"upstream-node-id", required_argument, NULL, OPT_UPSTREAM_NODE_ID}, {"without-barman", no_argument, NULL, OPT_WITHOUT_BARMAN}, {"replication-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY}, + {"verify-backup", no_argument, NULL, OPT_VERIFY_BACKUP }, /* deprecate this once Pg11 and earlier are unsupported */ {"recovery-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY},