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