Replace is_standby() with get_recovery_type()

We what to know what kind of node it is, not whether it's a standby or not.
This commit is contained in:
Ian Barwick
2017-06-09 11:25:43 +09:00
parent 056ed0328a
commit 124398bed5
4 changed files with 77 additions and 49 deletions

View File

@@ -825,14 +825,16 @@ get_server_version(PGconn *conn, char *server_version)
return atoi(PQgetvalue(res, 0, 0));
}
int
is_standby(PGconn *conn)
t_recovery_type
get_recovery_type(PGconn *conn)
{
PGresult *res;
int result = 0;
t_recovery_type recovery_type = RECTYPE_MASTER;
char *sqlquery = "SELECT pg_catalog.pg_is_in_recovery()";
log_verbose(LOG_DEBUG, "is_standby(): %s", sqlquery);
log_verbose(LOG_DEBUG, "get_recovery_type(): %s", sqlquery);
res = PQexec(conn, sqlquery);
@@ -840,15 +842,15 @@ is_standby(PGconn *conn)
{
log_error(_("unable to determine if server is in recovery:\n %s"),
PQerrorMessage(conn));
result = -1;
recovery_type = RECTYPE_UNKNOWN;
}
else if (PQntuples(res) == 1 && strcmp(PQgetvalue(res, 0, 0), "t") == 0)
{
result = 1;
recovery_type = RECTYPE_STANDBY;
}
PQclear(res);
return result;
return recovery_type;
}
/*
@@ -916,7 +918,7 @@ get_master_connection(PGconn *conn,
for (i = 0; i < PQntuples(res); i++)
{
int is_node_standby;
t_recovery_type recovery_type;
/* initialize with the values of the current node being processed */
node_id = atoi(PQgetvalue(res, i, 0));
@@ -929,9 +931,9 @@ get_master_connection(PGconn *conn,
if (PQstatus(remote_conn) != CONNECTION_OK)
continue;
is_node_standby = is_standby(remote_conn);
recovery_type = get_recovery_type(remote_conn);
if (is_node_standby == -1)
if (recovery_type == RECTYPE_UNKNOWN)
{
log_error(_("unable to retrieve recovery state from node %i:\n %s"),
node_id,
@@ -940,8 +942,7 @@ get_master_connection(PGconn *conn,
continue;
}
/* if is_standby() returns 0, queried node is the master */
if (is_node_standby == 0)
if (recovery_type == RECTYPE_MASTER)
{
PQclear(res);
log_debug(_("get_master_connection(): current master node is %i"), node_id);

View File

@@ -33,6 +33,12 @@ typedef enum {
REPMGR_UNKNOWN
} t_extension_status;
typedef enum {
RECTYPE_UNKNOWN = 0,
RECTYPE_MASTER,
RECTYPE_STANDBY
} t_recovery_type;
/*
* Struct to store node information
*/
@@ -165,7 +171,7 @@ bool get_pg_setting(PGconn *conn, const char *setting, char *output);
/* server information functions */
bool get_cluster_size(PGconn *conn, char *size);
int get_server_version(PGconn *conn, char *server_version);
int is_standby(PGconn *conn);
t_recovery_type get_recovery_type(PGconn *conn);
int get_master_node_id(PGconn *conn);
/* extension functions */

View File

@@ -18,8 +18,7 @@ do_master_register(void)
PGconn *conn = NULL;
PGconn *master_conn = NULL;
int current_master_id = UNKNOWN_NODE_ID;
int ret;
t_recovery_type recovery_type;
t_node_info node_info = T_NODE_INFO_INITIALIZER;
int record_found;
bool record_created;
@@ -35,14 +34,22 @@ do_master_register(void)
check_server_version(conn, "master", true, NULL);
/* check that node is actually a master */
ret = is_standby(conn);
if (ret)
{
log_error(_(ret == 1 ? "server is in standby mode and cannot be registered as a master" :
"connection to node lost!"));
recovery_type = get_recovery_type(conn);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
if (recovery_type != RECTYPE_STANDBY)
{
if (recovery_type == RECTYPE_MASTER)
{
log_error(_("server is in standby mode and cannot be registered as a master"));
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
else
{
log_error(_("connection to node lost"));
PQfinish(conn);
exit(ERR_DB_CONN);
}
}
log_verbose(LOG_INFO, _("server is not in recovery"));
@@ -204,3 +211,4 @@ do_master_register(void)
return;
}

View File

@@ -525,7 +525,6 @@ do_standby_register(void)
{
PGconn *conn;
PGconn *master_conn;
int ret;
bool record_created;
t_node_info node_record = T_NODE_INFO_INITIALIZER;
@@ -560,15 +559,24 @@ do_standby_register(void)
if (PQstatus(conn) == CONNECTION_OK)
{
ret = is_standby(conn);
t_recovery_type recovery_type = get_recovery_type(conn);
if (ret == 0 || ret == -1)
if (recovery_type != RECTYPE_STANDBY)
{
log_error(_(ret == 0 ? "this node should be a standby (%s)" :
"connection to node (%s) lost"), config_file_options.conninfo);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
if (recovery_type == RECTYPE_MASTER)
{
log_error(_("this node should be a standby (%s)"),
config_file_options.conninfo);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
else
{
log_error(_("connection to node (%s) lost"),
config_file_options.conninfo);
PQfinish(conn);
exit(ERR_DB_CONN);
}
}
}
@@ -997,9 +1005,8 @@ do_standby_promote(void)
char script[MAXLEN];
int r,
retval;
t_recovery_type recovery_type;
int r;
char data_dir[MAXLEN];
int i,
@@ -1018,18 +1025,22 @@ do_standby_promote(void)
check_server_version(conn, "standby", true, NULL);
/* Check we are in a standby node */
retval = is_standby(conn);
recovery_type = get_recovery_type(conn);
switch (retval)
if (recovery_type != RECTYPE_STANDBY)
{
case 0:
if (recovery_type == RECTYPE_MASTER)
{
log_error(_("STANDBY PROMOTE can only be executed on a standby node"));
PQfinish(conn);
exit(ERR_BAD_CONFIG);
case -1:
}
else
{
log_error(_("connection to node lost"));
PQfinish(conn);
exit(ERR_DB_CONN);
}
}
@@ -1094,8 +1105,9 @@ do_standby_promote(void)
for (i = 0; i < promote_check_timeout; i += promote_check_interval)
{
retval = is_standby(conn);
if (!retval)
recovery_type = get_recovery_type(conn);
if (recovery_type == RECTYPE_MASTER)
{
promote_success = true;
break;
@@ -1105,16 +1117,17 @@ do_standby_promote(void)
if (promote_success == false)
{
switch (retval)
if (recovery_type == RECTYPE_STANDBY)
{
case 1:
log_error(_("STANDBY PROMOTE failed, node is still a standby"));
PQfinish(conn);
exit(ERR_PROMOTION_FAIL);
default:
log_error(_("connection to node lost"));
PQfinish(conn);
exit(ERR_DB_CONN);
log_error(_("STANDBY PROMOTE failed, node is still a standby"));
PQfinish(conn);
exit(ERR_PROMOTION_FAIL);
}
else
{
log_error(_("connection to node lost"));
PQfinish(conn);
exit(ERR_DB_CONN);
}
}
@@ -1258,7 +1271,7 @@ check_source_server()
* If the upstream node is a standby, try to connect to the primary too so we
* can write an event record
*/
if (is_standby(source_conn))
if (get_recovery_type(source_conn) == RECTYPE_STANDBY)
{
primary_conn = get_master_connection(source_conn, NULL, NULL);