From d9db32401c1477fb63fb47a376fc0d08605dcc9b Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 22 Jun 2011 20:48:35 -0400 Subject: [PATCH] In pg_upgrade, check that the binary and data directories are the same major version. Backpatch to 9.1. Dan McGee --- contrib/pg_upgrade/check.c | 50 ++++++++++++++++++++++++++++++++- contrib/pg_upgrade/pg_upgrade.h | 1 + 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c index 377dea2b6f..ada93fb580 100644 --- a/contrib/pg_upgrade/check.c +++ b/contrib/pg_upgrade/check.c @@ -20,6 +20,7 @@ static void check_for_prepared_transactions(ClusterInfo *cluster); 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_support_lib(ClusterInfo *cluster); +static void get_bin_version(ClusterInfo *cluster); void @@ -217,6 +218,8 @@ output_completion_banner(char *deletion_script_file_name) void check_cluster_versions(void) { + prep_status("Checking cluster versions"); + /* get old and new cluster versions */ old_cluster.major_version = get_major_server_version(&old_cluster); new_cluster.major_version = get_major_server_version(&new_cluster); @@ -236,10 +239,26 @@ check_cluster_versions(void) /* * We can't allow downgrading because we use the target pg_dumpall, and - * pg_dumpall cannot operate on new datbase versions, only older versions. + * pg_dumpall cannot operate on new database versions, only older versions. */ if (old_cluster.major_version > new_cluster.major_version) pg_log(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)) + pg_log(PG_FATAL, + "Old cluster data and binary directories are from different major versions.\n"); + if (GET_MAJOR_VERSION(new_cluster.major_version) != + GET_MAJOR_VERSION(new_cluster.bin_version)) + pg_log(PG_FATAL, + "New cluster data and binary directories are from different major versions.\n"); + + check_ok(); } @@ -756,3 +775,32 @@ check_for_support_lib(ClusterInfo *cluster) fclose(lib_test); } + + +static void +get_bin_version(ClusterInfo *cluster) +{ + char cmd[MAXPGPATH], cmd_output[MAX_STRING]; + FILE *output; + int pre_dot, post_dot; + + snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" --version", cluster->bindir); + + if ((output = popen(cmd, "r")) == NULL) + pg_log(PG_FATAL, "Could not get pg_ctl version data: %s\n", + getErrorText(errno)); + + fgets(cmd_output, sizeof(cmd_output), output); + + 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) != 2) + pg_log(PG_FATAL, "could not get version from %s\n", cmd); + + cluster->bin_version = (pre_dot * 100 + post_dot) * 100; +} + diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h index c27b58aa58..613ddbd03f 100644 --- a/contrib/pg_upgrade/pg_upgrade.h +++ b/contrib/pg_upgrade/pg_upgrade.h @@ -184,6 +184,7 @@ typedef struct unsigned short port; /* port number where postmaster is waiting */ uint32 major_version; /* PG_VERSION of cluster */ char major_version_str[64]; /* string PG_VERSION of cluster */ + uint32 bin_version; /* version returned from pg_ctl */ Oid pg_database_oid; /* OID of pg_database relation */ char *tablespace_suffix; /* directory specification */ } ClusterInfo; -- 2.40.0