From 8f13a66aaa5405b8e8fa21b84d37afd637fe9d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Marqu=C3=A9s?= Date: Tue, 17 Jul 2018 14:00:37 -0300 Subject: [PATCH] Check that there is no exclusive backup taking place while we perform a switchover. We've found that this can cause some issues with postgres control metadata (could be a postgres bug) so best thing is *not* no switchover if there's a backup taking place. It's also a bad idea from an architectual point of view, as a switchover is supposed to be planed, so why perform it when we are taking backups. GitHub #476. --- dbutils.c | 24 ++++++++++++++++++++++++ dbutils.h | 1 + repmgr-action-standby.c | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/dbutils.c b/dbutils.c index 4bdf341e..607821df 100644 --- a/dbutils.c +++ b/dbutils.c @@ -3953,7 +3953,31 @@ connection_ping(PGconn *conn) return; } +/* + * Function that checks if the primary is in exclusive backup mode. + * We'll use this when executing an action can conflict with an exclusive + * backup. + */ +bool +server_not_in_exclusive_backup_mode(PGconn *conn) +{ + PGresult *res = PQexec(conn, "SELECT pg_is_in_backup()"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + log_error(_("unable to retrieve information regarding backup mode of node")); + log_detail("%s", PQerrorMessage(conn)); + PQclear(res); + return false; + } + + if (strcmp(PQgetvalue(res, 0, 0), "t") == 0) + { + log_warning(_("node is in exclusive backup mode")); + return false; + } + return true; +} /* ==================== */ /* monitoring functions */ diff --git a/dbutils.h b/dbutils.h index 2d39d9e6..3b765acb 100644 --- a/dbutils.h +++ b/dbutils.h @@ -467,6 +467,7 @@ int wait_connection_availability(PGconn *conn, long long timeout); bool is_server_available(const char *conninfo); bool is_server_available_params(t_conninfo_param_list *param_list); void connection_ping(PGconn *conn); +bool server_not_in_exclusive_backup_mode(PGconn *conn); /* monitoring functions */ void diff --git a/repmgr-action-standby.c b/repmgr-action-standby.c index c49916f3..d778a075 100644 --- a/repmgr-action-standby.c +++ b/repmgr-action-standby.c @@ -2911,6 +2911,24 @@ do_standby_switchover(void) exit(ERR_DB_QUERY); } + /* + * Check that there's no exclusive backups running on the primary. + * We don't want to end up damaging the backup and also leaving the server in an + * state where there's control data saying it's in backup mode but there's no + * backup_label in PGDATA. + * If the DBA wants to do the switchover anyway, he should first stop the + * backup that's running. + */ + if (!server_not_in_exclusive_backup_mode(remote_conn)) + { + log_error(_("can't perform a switchover while primary server is in exclusive backup mode")); + log_hint(_("stop backup before attempting the switchover")); + + PQfinish(remote_conn); + + exit(ERR_SWITCHOVER_FAIL); + } + /* * Check this standby is attached to the demotion candidate * TODO: