From 219b4431b4a659b4630420b1fbc24704c1364d36 Mon Sep 17 00:00:00 2001 From: Jaime Casanova Date: Sat, 23 Oct 2010 15:27:24 -0500 Subject: [PATCH] Replace the function is_supported_version() with the function pg_version() the main difference is that this new function doesn't return a bool but a string representing the current major version of the postgresql server or an empty string if it's earlier than 9.0. Teach all commands that could connect to master and standby that they both should have the same major version. --- dbutils.c | 30 ++++++++++++++++---- dbutils.h | 2 +- repmgr.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++------ repmgrd.c | 10 +++++++ 4 files changed, 110 insertions(+), 15 deletions(-) diff --git a/dbutils.c b/dbutils.c index 7c8304e6..25a22ded 100644 --- a/dbutils.c +++ b/dbutils.c @@ -56,13 +56,21 @@ is_standby(PGconn *conn) } -bool -is_supported_version(PGconn *conn) +/* + * If postgreSQL version is 9 or superior returns the major version + * if 8 or inferior returns an empty string + */ +char * +pg_version(PGconn *conn) { PGresult *res; - int major_version; + char *major_version; - res = PQexec(conn, "SELECT split_part(split_part(version(), ' ', 2), '.', 1)"); + int major_version1; + char *major_version2; + + res = PQexec(conn, "WITH pg_version(ver) AS (SELECT split_part(version(), ' ', 2)) " + "SELECT split_part(ver, '.', 1), split_part(ver, '.', 2) FROM pg_version"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "PQexec failed: %s", PQerrorMessage(conn)); @@ -70,10 +78,20 @@ is_supported_version(PGconn *conn) PQfinish(conn); exit(1); } - major_version = atoi(PQgetvalue(res, 0, 0)); + major_version1 = atoi(PQgetvalue(res, 0, 0)); + major_version2 = PQgetvalue(res, 0, 1); PQclear(res); - return (major_version >= 9) ? true : false; + major_version = malloc(10); + if (major_version1 >= 9) + { + /* form a major version string */ + sprintf(major_version, "%d.%s", major_version1, major_version2); + } + else + strcpy(major_version, ""); + + return major_version; } diff --git a/dbutils.h b/dbutils.h index 90e97ee4..a1f96a3f 100644 --- a/dbutils.h +++ b/dbutils.h @@ -6,7 +6,7 @@ PGconn *establishDBConnection(const char *conninfo, const bool exit_on_error); bool is_standby(PGconn *conn); -bool is_supported_version(PGconn *conn); +char *pg_version(PGconn *conn); bool guc_setted(PGconn *conn, const char *parameter, const char *op, const char *value); const char *get_cluster_size(PGconn *conn); PGconn * getMasterConnection(PGconn *standby_conn, int id, char *cluster, int *master_id); diff --git a/repmgr.c b/repmgr.c index 51310369..77e12c02 100644 --- a/repmgr.c +++ b/repmgr.c @@ -269,6 +269,7 @@ do_master_register(void) char conninfo[MAXLEN]; bool schema_exists = false; + const char *master_version = NULL; /* * Read the configuration file: repmgr.conf @@ -283,6 +284,15 @@ do_master_register(void) conn = establishDBConnection(conninfo, true); + /* master should be v9 or better */ + master_version = pg_version(conn); + if (strcmp(master_version, "") == 0) + { + PQfinish(conn); + fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname); + return; + } + /* Check we are a master */ if (is_standby(conn)) { @@ -436,6 +446,9 @@ do_standby_register(void) int myLocalId = -1; char conninfo[MAXLEN]; + const char *master_version = NULL; + const char *standby_version = NULL; + /* * Read the configuration file: repmgr.conf */ @@ -449,6 +462,15 @@ do_standby_register(void) conn = establishDBConnection(conninfo, true); + /* should be v9 or better */ + standby_version = pg_version(conn); + if (strcmp(standby_version, "") == 0) + { + PQfinish(conn); + fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); + return; + } + /* Check we are a standby */ if (!is_standby(conn)) { @@ -482,6 +504,27 @@ do_standby_register(void) if (!master_conn) return; + /* master should be v9 or better */ + master_version = pg_version(master_conn); + if (strcmp(master_version, "") == 0) + { + PQfinish(conn); + PQfinish(master_conn); + fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname); + return; + } + + /* master and standby version should match */ + if (strcmp(master_version, standby_version) == 0) + { + PQfinish(conn); + PQfinish(master_conn); + fprintf(stderr, _("%s needs versions of both master (%s) and standby (%s) to match.\n"), + progname, master_version, standby_version); + return; + } + + /* Now register the standby */ if (force) { @@ -517,6 +560,7 @@ do_standby_register(void) return; } + static void do_standby_clone(void) { @@ -538,6 +582,8 @@ do_standby_clone(void) const char *first_wal_segment = NULL; const char *last_wal_segment = NULL; + const char *master_version = NULL; + /* if dest_dir hasn't been provided, initialize to current directory */ if (dest_dir == NULL) { @@ -619,10 +665,11 @@ do_standby_clone(void) } /* primary should be v9 or better */ - if (!is_supported_version(conn)) + master_version = pg_version(conn); + if (strcmp(master_version, "") == 0) { PQfinish(conn); - fprintf(stderr, _("%s needs PostgreSQL 9.0 or better\n"), progname); + fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname); return; } @@ -903,6 +950,8 @@ do_standby_promote(void) char recovery_file_path[MAXLEN]; char recovery_done_path[MAXLEN]; + const char *standby_version = NULL; + /* * Read the configuration file: repmgr.conf */ @@ -917,10 +966,12 @@ do_standby_promote(void) /* We need to connect to check configuration */ conn = establishDBConnection(conninfo, true); - if (!is_supported_version(conn)) + /* we need v9 or better */ + standby_version = pg_version(conn); + if (strcmp(standby_version, "") == 0) { PQfinish(conn); - fprintf(stderr, _("%s needs PostgreSQL 9.0 or better\n"), progname); + fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); return; } @@ -993,6 +1044,9 @@ do_standby_follow(void) int r; char data_dir[MAXLEN]; + const char *master_version = NULL; + const char *standby_version = NULL; + /* * Read the configuration file: repmgr.conf */ @@ -1015,10 +1069,11 @@ do_standby_follow(void) } /* should be v9 or better */ - if (!is_supported_version(conn)) + standby_version = pg_version(conn); + if (strcmp(standby_version, "") == 0) { PQfinish(conn); - fprintf(stderr, _("\n%s needs PostgreSQL 9.0 or better\n"), progname); + fprintf(stderr, _("\n%s needs standby to be PostgreSQL 9.0 or better\n"), progname); return; } @@ -1040,13 +1095,25 @@ do_standby_follow(void) } /* should be v9 or better */ - if (!is_supported_version(master_conn)) + master_version = pg_version(master_conn); + if (strcmp(master_version, "") == 0) { PQfinish(conn); PQfinish(master_conn); - fprintf(stderr, _("%s needs PostgreSQL 9.0 or better\n"), progname); + fprintf(stderr, _("%s needs master to be PostgreSQL 9.0 or better\n"), progname); return; } + + /* master and standby version should match */ + if (strcmp(master_version, standby_version) == 0) + { + PQfinish(conn); + PQfinish(master_conn); + fprintf(stderr, _("%s needs versions of both master (%s) and standby (%s) to match.\n"), + progname, master_version, standby_version); + return; + } + PQfinish(master_conn); if (verbose) diff --git a/repmgrd.c b/repmgrd.c index 288b31c4..befa06c4 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -81,6 +81,7 @@ main(int argc, char **argv) int c; char conninfo[MAXLEN]; + const char *standby_version = NULL; progname = get_progname(argv[0]); @@ -136,6 +137,15 @@ main(int argc, char **argv) myLocalConn = establishDBConnection(conninfo, true); + /* should be v9 or better */ + standby_version = pg_version(myLocalConn); + if (strcmp(standby_version, "") == 0) + { + PQfinish(myLocalConn); + fprintf(stderr, _("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); + exit(1); + } + /* * Set my server mode, establish a connection to primary * and start monitor