repmgrd: check binary and extension major versions match

repmgr requires that the same "major version" (e.g. 4.3) is present
on all nodes, otherwise - particularly in the case of repmgrd - it's
highly likely things won't work as expected.

Implements part of GitHub #515.
This commit is contained in:
Ian Barwick
2018-12-18 10:34:01 +09:00
parent 40410e43ab
commit 40408a1734
5 changed files with 46 additions and 5 deletions

View File

@@ -1,3 +1,6 @@
4.3 2019-??
repmgrd: check binary and extension major versions match; GitHub #515 (Ian)
4.2.1 2018-??-??
repmgr: add sanity check for correct extension version (Ian)
repmgr: ensure "witness register --dry-run" does not attempt to read node

View File

@@ -1904,9 +1904,9 @@ get_repmgr_extension_status(PGconn *conn, t_extension_versions *extversions)
appendPQExpBufferStr(&query,
" SELECT ae.name, e.extname, "
" ae.default_version, "
" (ae.default_version::numeric * 10)::INT AS available, "
" (((ae.default_version::NUMERIC::INT) * 10000) + (ae.default_version::NUMERIC - ae.default_version::NUMERIC::INT) * 1000)::INT AS available, "
" ae.installed_version, "
" (ae.installed_version::numeric * 10)::INT AS installed "
" (((ae.installed_version::NUMERIC::INT) * 10000) + (ae.installed_version::NUMERIC - ae.installed_version::NUMERIC::INT) * 1000)::INT AS installed "
" FROM pg_catalog.pg_available_extensions ae "
"LEFT JOIN pg_catalog.pg_extension e "
" ON e.extname=ae.name "
@@ -1936,7 +1936,9 @@ get_repmgr_extension_status(PGconn *conn, t_extension_versions *extversions)
if (extversions != NULL)
{
strncpy(extversions->default_version, PQgetvalue(res, 0, 2), 7);
extversions->default_version_num = available_version;
strncpy(extversions->installed_version, PQgetvalue(res, 0, 4), 7);
extversions->installed_version_num = installed_version;
}
if (available_version > installed_version)

View File

@@ -112,12 +112,16 @@ typedef enum
typedef struct s_extension_versions {
char default_version[8];
int default_version_num;
char installed_version[8];
int installed_version_num;
} t_extension_versions;
#define T_EXTENSION_VERSIONS_INITIALIZER { \
"", \
UNKNOWN_SERVER_VERSION_NUM, \
"", \
UNKNOWN_SERVER_VERSION_NUM \
}
/*

View File

@@ -1,2 +1,3 @@
#define REPMGR_VERSION_DATE ""
#define REPMGR_VERSION "4.3dev"
#define REPMGR_VERSION_NUM 40300

View File

@@ -386,7 +386,39 @@ main(int argc, char **argv)
/* Check "repmgr" the extension is installed */
extension_status = get_repmgr_extension_status(local_conn, &extversions);
if (extension_status != REPMGR_INSTALLED)
if (extension_status == REPMGR_INSTALLED)
{
/*
* extension is the latest available according to "pg_available_extensions" -
* - does our (major) version match that?
*/
log_verbose(LOG_DEBUG, "binary version: %i; extension version: %i",
REPMGR_VERSION_NUM, extversions.installed_version_num);
if ((REPMGR_VERSION_NUM/100) < (extversions.installed_version_num / 100))
{
log_error(_("this \"repmgr\" version is older than the installed \"repmgr\" extension version"));
log_detail(_("\"repmgr\" version %s is installed but extension is version %s"),
REPMGR_VERSION,
extversions.installed_version);
log_hint(_("verify the repmgr installation on this server is updated properly before continuing"));
close_connection(&local_conn);
exit(ERR_BAD_CONFIG);
}
if ((REPMGR_VERSION_NUM/100) > (extversions.installed_version_num / 100))
{
log_error(_("this \"repmgr\" version is newer than the installed \"repmgr\" extension version"));
log_detail(_("\"repmgr\" version %s is installed but extension is version %s"),
REPMGR_VERSION,
extversions.installed_version);
log_hint(_("verify the repmgr extension is updated properly before continuing"));
close_connection(&local_conn);
exit(ERR_BAD_CONFIG);
}
}
else
{
/* this is unlikely to happen */
if (extension_status == REPMGR_UNKNOWN)
@@ -400,11 +432,10 @@ main(int argc, char **argv)
if (extension_status == REPMGR_OLD_VERSION_INSTALLED)
{
log_error(_("an older version of the \"repmgr\" extension is installed"));
log_detail(_("version %s is installed but newer version %s is available"),
log_detail(_("extension version %s is installed but newer version %s is available"),
extversions.installed_version,
extversions.default_version);
log_hint(_("verify the repmgr installation is updated properly before continuing"));
}
else
{