From: Robert Haas Date: Wed, 15 Feb 2017 15:14:16 +0000 (-0500) Subject: pg_upgrade: Fix problems caused by renaming pg_resetxlog. X-Git-Tag: REL_10_BETA1~895 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b8777611230ac94734ea99004d2a7d4266f9a954;p=postgresql pg_upgrade: Fix problems caused by renaming pg_resetxlog. Commit 85c11324cabaddcfaf3347df78555b30d27c5b5a renamed pg_resetxlog to pg_resetwal, but didn't make pg_upgrade smart enough to cope with the situation. Michael Paquier, per a complaint from Jeff Janes --- diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index ff1d7a207a..d52c81e249 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -26,7 +26,6 @@ static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster); static void check_for_reg_data_type_usage(ClusterInfo *cluster); static void check_for_jsonb_9_4_usage(ClusterInfo *cluster); static void check_for_pg_role_prefix(ClusterInfo *cluster); -static void get_bin_version(ClusterInfo *cluster); static char *get_canonical_locale_name(int category, const char *locale); @@ -241,10 +240,6 @@ check_cluster_versions(void) if (old_cluster.major_version > new_cluster.major_version) pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n"); - /* get old and new binary versions */ - get_bin_version(&old_cluster); - get_bin_version(&new_cluster); - /* Ensure binaries match the designated data directories */ if (GET_MAJOR_VERSION(old_cluster.major_version) != GET_MAJOR_VERSION(old_cluster.bin_version)) @@ -1080,34 +1075,6 @@ check_for_pg_role_prefix(ClusterInfo *cluster) check_ok(); } -static void -get_bin_version(ClusterInfo *cluster) -{ - char cmd[MAXPGPATH], - cmd_output[MAX_STRING]; - FILE *output; - int pre_dot = 0, - post_dot = 0; - - snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" --version", cluster->bindir); - - if ((output = popen(cmd, "r")) == NULL || - fgets(cmd_output, sizeof(cmd_output), output) == NULL) - pg_fatal("could not get pg_ctl version data using %s: %s\n", - cmd, strerror(errno)); - - pclose(output); - - /* Remove trailing newline */ - if (strchr(cmd_output, '\n') != NULL) - *strchr(cmd_output, '\n') = '\0'; - - if (sscanf(cmd_output, "%*s %*s %d.%d", &pre_dot, &post_dot) < 1) - pg_fatal("could not get version from %s\n", cmd); - - cluster->bin_version = (pre_dot * 100 + post_dot) * 100; -} - /* * get_canonical_locale_name diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c index b075e26632..519256851c 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -70,6 +70,7 @@ get_control_data(ClusterInfo *cluster, bool live_check) uint32 tli = 0; uint32 logid = 0; uint32 segno = 0; + char *resetwal_bin; /* @@ -111,9 +112,14 @@ get_control_data(ClusterInfo *cluster, bool live_check) pg_putenv("LC_ALL", NULL); pg_putenv("LC_MESSAGES", "C"); + /* pg_resetxlog has been renamed to pg_resetwal in version 10 */ + if (GET_MAJOR_VERSION(cluster->bin_version) < 1000) + resetwal_bin = "pg_resetxlog\" -n"; + else + resetwal_bin = "pg_resetwal\" -n"; snprintf(cmd, sizeof(cmd), "\"%s/%s \"%s\"", cluster->bindir, - live_check ? "pg_controldata\"" : "pg_resetwal\" -n", + live_check ? "pg_controldata\"" : resetwal_bin, cluster->pgdata); fflush(stdout); fflush(stderr); diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c index c74521f24a..b6a3ef791e 100644 --- a/src/bin/pg_upgrade/exec.c +++ b/src/bin/pg_upgrade/exec.c @@ -16,6 +16,7 @@ static void check_data_dir(ClusterInfo *cluster); static void check_bin_dir(ClusterInfo *cluster); +static void get_bin_version(ClusterInfo *cluster); static void validate_exec(const char *dir, const char *cmdName); #ifdef WIN32 @@ -23,6 +24,40 @@ static int win32_check_directory_write_permissions(void); #endif +/* + * get_bin_version + * + * Fetch versions of binaries for cluster. + */ +static void +get_bin_version(ClusterInfo *cluster) +{ + char cmd[MAXPGPATH], + cmd_output[MAX_STRING]; + FILE *output; + int pre_dot = 0, + post_dot = 0; + + snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" --version", cluster->bindir); + + if ((output = popen(cmd, "r")) == NULL || + fgets(cmd_output, sizeof(cmd_output), output) == NULL) + pg_fatal("could not get pg_ctl version data using %s: %s\n", + cmd, strerror(errno)); + + pclose(output); + + /* Remove trailing newline */ + if (strchr(cmd_output, '\n') != NULL) + *strchr(cmd_output, '\n') = '\0'; + + if (sscanf(cmd_output, "%*s %*s %d.%d", &pre_dot, &post_dot) < 1) + pg_fatal("could not get version from %s\n", cmd); + + cluster->bin_version = (pre_dot * 100 + post_dot) * 100; +} + + /* * exec_prog() * Execute an external program with stdout/stderr redirected, and report @@ -335,7 +370,20 @@ check_bin_dir(ClusterInfo *cluster) validate_exec(cluster->bindir, "postgres"); validate_exec(cluster->bindir, "pg_ctl"); - validate_exec(cluster->bindir, "pg_resetwal"); + + /* + * Fetch the binary versions after checking for the existence of pg_ctl, + * this gives a correct error if the binary used itself for the version + * fetching is broken. + */ + get_bin_version(&old_cluster); + get_bin_version(&new_cluster); + + /* pg_resetxlog has been renamed to pg_resetwal in version 10 */ + if (GET_MAJOR_VERSION(cluster->bin_version) < 1000) + validate_exec(cluster->bindir, "pg_resetxlog"); + else + validate_exec(cluster->bindir, "pg_resetwal"); if (cluster == &new_cluster) { /* these are only needed in the new cluster */