Add "standby unregister"

This commit is contained in:
Ian Barwick
2017-05-08 23:37:53 +09:00
parent 08d2da3443
commit c7f49541a3
5 changed files with 124 additions and 2 deletions

View File

@@ -1360,6 +1360,37 @@ _create_update_node_record(PGconn *conn, char *action, t_node_info *node_info)
return true; return true;
} }
bool
delete_node_record(PGconn *conn, int node)
{
PQExpBufferData query;
PGresult *res;
initPQExpBuffer(&query);
appendPQExpBuffer(&query,
"DELETE FROM repmgr.nodes "
" WHERE node_id = %d",
node);
log_verbose(LOG_DEBUG, "delete_node_record():\n %s", query.data);
res = PQexec(conn, query.data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
{
log_error(_("unable to delete node record:\n %s"),
PQerrorMessage(conn));
PQclear(res);
return false;
}
PQclear(res);
return true;
}
/* ====================== */ /* ====================== */
/* event record functions */ /* event record functions */
/* ====================== */ /* ====================== */

View File

@@ -132,6 +132,8 @@ PGconn *establish_db_connection_by_params(const char *keywords[],
const char *values[], const char *values[],
const bool exit_on_error); const bool exit_on_error);
PGconn *get_master_connection(PGconn *standby_conn, int *master_id, char *master_conninfo_out);
bool is_superuser_connection(PGconn *conn, t_connection_user *userinfo); bool is_superuser_connection(PGconn *conn, t_connection_user *userinfo);
/* conninfo manipulation functions */ /* conninfo manipulation functions */
@@ -164,7 +166,6 @@ bool get_pg_setting(PGconn *conn, const char *setting, char *output);
bool get_cluster_size(PGconn *conn, char *size); bool get_cluster_size(PGconn *conn, char *size);
int get_server_version(PGconn *conn, char *server_version); int get_server_version(PGconn *conn, char *server_version);
int is_standby(PGconn *conn); int is_standby(PGconn *conn);
PGconn *get_master_connection(PGconn *standby_conn, int *master_id, char *master_conninfo_out);
int get_master_node_id(PGconn *conn); int get_master_node_id(PGconn *conn);
/* extension functions */ /* extension functions */
@@ -182,6 +183,7 @@ int get_node_record_by_name(PGconn *conn, const char *node_name, t_node_info *
bool create_node_record(PGconn *conn, char *repmgr_action, t_node_info *node_info); bool create_node_record(PGconn *conn, char *repmgr_action, t_node_info *node_info);
bool update_node_record(PGconn *conn, char *repmgr_action, t_node_info *node_info); bool update_node_record(PGconn *conn, char *repmgr_action, t_node_info *node_info);
bool delete_node_record(PGconn *conn, int node);
/* event record functions */ /* event record functions */
bool create_event_record(PGconn *conn, t_configuration_options *options, int node_id, char *event, bool successful, char *details); bool create_event_record(PGconn *conn, t_configuration_options *options, int node_id, char *event, bool successful, char *details);

View File

@@ -930,6 +930,88 @@ do_standby_register(void)
} }
void
do_standby_unregister(void)
{
PGconn *conn;
PGconn *master_conn;
int target_node_id;
t_node_info node_info = T_NODE_INFO_INITIALIZER;
bool node_record_deleted;
log_info(_("connecting to local standby"));
conn = establish_db_connection(config_file_options.conninfo, true);
/* check if there is a master in this cluster */
log_info(_("connecting to master database"));
master_conn = get_master_connection(conn, NULL, NULL);
if (PQstatus(master_conn) != CONNECTION_OK)
{
log_error(_("unable to connect to master server"));
log_detail("%s", PQerrorMessage(conn));
exit(ERR_BAD_CONFIG);
}
/*
* if --node-id was specified, unregister that node rather than the
* current one - this enables inactive nodes to be unregistered.
*/
if (runtime_options.node_id != UNKNOWN_NODE_ID)
target_node_id = runtime_options.node_id;
else
target_node_id = config_file_options.node_id;
/* Check node exists and is really a standby */
if (!get_node_record(master_conn, target_node_id, &node_info))
{
log_error(_("no record found for node %i"), target_node_id);
PQfinish(master_conn);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
if (node_info.type != STANDBY)
{
log_error(_("node %i is not a standby server"), target_node_id);
PQfinish(master_conn);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
/* Now unregister the standby */
log_notice(_("unregistering node %i"), target_node_id);
node_record_deleted = delete_node_record(master_conn,
target_node_id);
if (node_record_deleted == false)
{
PQfinish(master_conn);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
/* Log the event */
create_event_record(master_conn,
&config_file_options,
target_node_id,
"standby_unregister",
true,
NULL);
PQfinish(master_conn);
PQfinish(conn);
log_info(_("standby unregistration complete"));
return;
}
static void static void
check_source_server() check_source_server()
{ {

View File

@@ -8,6 +8,7 @@
extern void do_standby_clone(void); extern void do_standby_clone(void);
extern void do_standby_register(void); extern void do_standby_register(void);
extern void do_standby_unregister(void);
typedef struct typedef struct
{ {

View File

@@ -11,7 +11,8 @@
* [ MASTER | PRIMARY ] REGISTER * [ MASTER | PRIMARY ] REGISTER
* *
* STANDBY CLONE * STANDBY CLONE
* STANDBY REGISTER (wip) * STANDBY REGISTER
* STANDBY UNREGISTER (wip)
* *
* CLUSTER EVENT * CLUSTER EVENT
*/ */
@@ -558,6 +559,8 @@ main(int argc, char **argv)
action = STANDBY_CLONE; action = STANDBY_CLONE;
else if(strcasecmp(repmgr_action, "REGISTER") == 0) else if(strcasecmp(repmgr_action, "REGISTER") == 0)
action = STANDBY_REGISTER; action = STANDBY_REGISTER;
else if(strcasecmp(repmgr_action, "UNREGISTER") == 0)
action = STANDBY_UNREGISTER;
} }
else if(strcasecmp(repmgr_node_type, "CLUSTER") == 0) else if(strcasecmp(repmgr_node_type, "CLUSTER") == 0)
@@ -814,6 +817,9 @@ main(int argc, char **argv)
case STANDBY_REGISTER: case STANDBY_REGISTER:
do_standby_register(); do_standby_register();
break; break;
case STANDBY_UNREGISTER:
do_standby_unregister();
break;
case CLUSTER_EVENT: case CLUSTER_EVENT:
do_cluster_event(); do_cluster_event();