mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
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:
3
HISTORY
3
HISTORY
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 \
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
#define REPMGR_VERSION_DATE ""
|
||||
#define REPMGR_VERSION "4.3dev"
|
||||
#define REPMGR_VERSION_NUM 40300
|
||||
|
||||
37
repmgrd.c
37
repmgrd.c
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user