mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-26 08:36:30 +00:00
repmgr: prevent a standby being cloned from a witness server
Previously repmgr would happily clone from whatever server it found at the provided source server address. We should ensure that a standby can only be cloned from a node which is part of the main replication cluster. This check fetches a list of nodes from the source server, connects to the first non-witness server it finds, and compares the system identifiers of the source node and the node it has connected to. If there is a mismatch, then the source server is clearly not part of the main replication cluster, and is most likely the witness server.
This commit is contained in:
39
dbutils.c
39
dbutils.c
@@ -1551,12 +1551,12 @@ get_ready_archive_files(PGconn *conn, const char *data_directory)
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
identify_system(PGconn *repl_conn, t_system_identification *identification)
|
||||
{
|
||||
PGresult *res = NULL;
|
||||
|
||||
/* semicolon required here */
|
||||
res = PQexec(repl_conn, "IDENTIFY_SYSTEM;");
|
||||
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK || !PQntuples(res))
|
||||
@@ -1576,6 +1576,43 @@ identify_system(PGconn *repl_conn, t_system_identification *identification)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the system identifier by querying pg_control_system().
|
||||
*
|
||||
* Note there is a similar function in controldata.c ("get_system_identifier()")
|
||||
* which reads the control file.
|
||||
*/
|
||||
uint64
|
||||
system_identifier(PGconn *conn)
|
||||
{
|
||||
uint64 system_identifier = UNKNOWN_SYSTEM_IDENTIFIER;
|
||||
PGresult *res = NULL;
|
||||
|
||||
/*
|
||||
* pg_control_system() was introduced in PostgreSQL 9.6
|
||||
*/
|
||||
if (PQserverVersion(conn) < 90600)
|
||||
{
|
||||
return UNKNOWN_SYSTEM_IDENTIFIER;
|
||||
}
|
||||
|
||||
res = PQexec(conn, "SELECT system_identifier FROM pg_catalog.pg_control_system()");
|
||||
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
log_db_error(conn, NULL, _("get_system_identifier(): unable to query pg_control_system()"));
|
||||
}
|
||||
else
|
||||
{
|
||||
system_identifier = atol(PQgetvalue(res, 0, 0));
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
|
||||
return system_identifier;
|
||||
}
|
||||
|
||||
|
||||
TimeLineHistoryEntry *
|
||||
get_timeline_history(PGconn *repl_conn, TimeLineID tli)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user