mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
Merge pull request #115 from xocolatl/unregister
Add a STANDBY UNREGISTER command.
This commit is contained in:
@@ -350,6 +350,7 @@ Following event types currently exist:
|
||||
|
||||
master_register
|
||||
standby_register
|
||||
standby_unregister
|
||||
standby_clone
|
||||
standby_promote
|
||||
witness_create
|
||||
@@ -458,6 +459,11 @@ its port if is different from the default one.
|
||||
promote/follow operations and to allow `repmgrd` to work with the node.
|
||||
An existing standby can be registered using this command.
|
||||
|
||||
* `standby unregister`
|
||||
|
||||
Unregisters a standby with `repmgr`. This command does not affect the actual
|
||||
replication.
|
||||
|
||||
* `standby clone [node to be cloned]`
|
||||
|
||||
Clones a new standby node from the data directory of the master (or
|
||||
|
||||
131
repmgr.c
131
repmgr.c
@@ -10,6 +10,7 @@
|
||||
* MASTER REGISTER
|
||||
*
|
||||
* STANDBY REGISTER
|
||||
* STANDBY UNREGISTER
|
||||
* STANDBY CLONE
|
||||
* STANDBY FOLLOW
|
||||
* STANDBY PROMOTE
|
||||
@@ -53,15 +54,16 @@
|
||||
|
||||
#define RECOVERY_FILE "recovery.conf"
|
||||
|
||||
#define NO_ACTION 0 /* Dummy default action */
|
||||
#define MASTER_REGISTER 1
|
||||
#define STANDBY_REGISTER 2
|
||||
#define STANDBY_CLONE 3
|
||||
#define STANDBY_PROMOTE 4
|
||||
#define STANDBY_FOLLOW 5
|
||||
#define WITNESS_CREATE 6
|
||||
#define CLUSTER_SHOW 7
|
||||
#define CLUSTER_CLEANUP 8
|
||||
#define NO_ACTION 0 /* Dummy default action */
|
||||
#define MASTER_REGISTER 1
|
||||
#define STANDBY_REGISTER 2
|
||||
#define STANDBY_UNREGISTER 3
|
||||
#define STANDBY_CLONE 4
|
||||
#define STANDBY_PROMOTE 5
|
||||
#define STANDBY_FOLLOW 6
|
||||
#define WITNESS_CREATE 7
|
||||
#define CLUSTER_SHOW 8
|
||||
#define CLUSTER_CLEANUP 9
|
||||
|
||||
|
||||
|
||||
@@ -83,6 +85,7 @@ static char *make_pg_path(char *file);
|
||||
|
||||
static void do_master_register(void);
|
||||
static void do_standby_register(void);
|
||||
static void do_standby_unregister(void);
|
||||
static void do_standby_clone(void);
|
||||
static void do_standby_promote(void);
|
||||
static void do_standby_follow(void);
|
||||
@@ -293,8 +296,10 @@ main(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* Now we need to obtain the action, this comes in one of these forms:
|
||||
* MASTER REGISTER | STANDBY {REGISTER | CLONE [node] | PROMOTE | FOLLOW
|
||||
* [node]} | WITNESS CREATE CLUSTER {SHOW | CLEANUP}
|
||||
* MASTER REGISTER |
|
||||
* STANDBY {REGISTER | UNREGISTER | CLONE [node] | PROMOTE | FOLLOW [node]} |
|
||||
* WITNESS CREATE |
|
||||
* CLUSTER {SHOW | CLEANUP}
|
||||
*
|
||||
* the node part is optional, if we receive it then we shouldn't have
|
||||
* received a -h option
|
||||
@@ -327,6 +332,8 @@ main(int argc, char **argv)
|
||||
{
|
||||
if (strcasecmp(server_cmd, "REGISTER") == 0)
|
||||
action = STANDBY_REGISTER;
|
||||
if (strcasecmp(server_cmd, "UNREGISTER") == 0)
|
||||
action = STANDBY_UNREGISTER;
|
||||
else if (strcasecmp(server_cmd, "CLONE") == 0)
|
||||
action = STANDBY_CLONE;
|
||||
else if (strcasecmp(server_cmd, "PROMOTE") == 0)
|
||||
@@ -535,6 +542,9 @@ main(int argc, char **argv)
|
||||
case STANDBY_REGISTER:
|
||||
do_standby_register();
|
||||
break;
|
||||
case STANDBY_UNREGISTER:
|
||||
do_standby_unregister();
|
||||
break;
|
||||
case STANDBY_CLONE:
|
||||
do_standby_clone();
|
||||
break;
|
||||
@@ -901,6 +911,85 @@ do_standby_register(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_standby_unregister(void)
|
||||
{
|
||||
PGconn *conn;
|
||||
PGconn *master_conn;
|
||||
int ret;
|
||||
|
||||
bool node_record_deleted;
|
||||
|
||||
log_info(_("connecting to standby database\n"));
|
||||
conn = establish_db_connection(options.conninfo, true);
|
||||
|
||||
/* Check we are a standby */
|
||||
ret = is_standby(conn);
|
||||
if (ret == 0 || ret == -1)
|
||||
{
|
||||
log_err(_(ret == 0 ? "this node should be a standby (%s)\n" :
|
||||
"connection to node (%s) lost\n"), options.conninfo);
|
||||
|
||||
PQfinish(conn);
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/* Check if there is a schema for this cluster */
|
||||
if (check_cluster_schema(conn) == false)
|
||||
{
|
||||
/* schema doesn't exist */
|
||||
log_err(_("schema '%s' doesn't exist.\n"), get_repmgr_schema());
|
||||
PQfinish(conn);
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/* check if there is a master in this cluster */
|
||||
log_info(_("connecting to master database\n"));
|
||||
master_conn = get_master_connection(conn, options.cluster_name,
|
||||
NULL, NULL);
|
||||
if (!master_conn)
|
||||
{
|
||||
log_err(_("a master must be defined before configuring a slave\n"));
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that standby and master are supported and compatible server
|
||||
* versions
|
||||
*/
|
||||
check_master_standby_version_match(conn, master_conn);
|
||||
|
||||
/* Now unregister the standby */
|
||||
log_info(_("unregistering the standby\n"));
|
||||
node_record_deleted = delete_node_record(master_conn,
|
||||
options.node,
|
||||
"standby unregister");
|
||||
|
||||
if (node_record_deleted == false)
|
||||
{
|
||||
PQfinish(master_conn);
|
||||
PQfinish(conn);
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/* Log the event */
|
||||
create_event_record(master_conn,
|
||||
&options,
|
||||
options.node,
|
||||
"standby_unregister",
|
||||
true,
|
||||
NULL);
|
||||
|
||||
PQfinish(master_conn);
|
||||
PQfinish(conn);
|
||||
|
||||
log_info(_("standby unregistration complete\n"));
|
||||
log_notice(_("standby node correctly unregistered for cluster %s with id %d (conninfo: %s)\n"),
|
||||
options.cluster_name, options.node, options.conninfo);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_standby_clone(void)
|
||||
{
|
||||
@@ -2224,7 +2313,7 @@ help(const char *progname)
|
||||
printf(_("\n"));
|
||||
printf(_("Usage:\n"));
|
||||
printf(_(" %s [OPTIONS] master {register}\n"), progname);
|
||||
printf(_(" %s [OPTIONS] standby {register|clone|promote|follow}\n"),
|
||||
printf(_(" %s [OPTIONS] standby {register|unregister|clone|promote|follow}\n"),
|
||||
progname);
|
||||
printf(_(" %s [OPTIONS] cluster {show|cleanup}\n"), progname);
|
||||
printf(_("\n"));
|
||||
@@ -2264,6 +2353,7 @@ help(const char *progname)
|
||||
printf(_(" master register - registers the master in a cluster\n"));
|
||||
printf(_(" standby clone [node] - creates a new standby\n"));
|
||||
printf(_(" standby register - registers a standby in a cluster\n"));
|
||||
printf(_(" standby unregister - unregisters a standby in a cluster\n"));
|
||||
printf(_(" standby promote - promotes a specific standby to master\n"));
|
||||
printf(_(" standby follow - makes standby follow a new master\n"));
|
||||
printf(_(" cluster show - displays information about cluster nodes\n"));
|
||||
@@ -2597,6 +2687,23 @@ check_parameters_for_action(const int action)
|
||||
error_list_append(_("destination directory not required when executing STANDBY REGISTER"));
|
||||
}
|
||||
break;
|
||||
case STANDBY_UNREGISTER:
|
||||
|
||||
/*
|
||||
* To unregister a standby we only need the repmgr.conf we don't
|
||||
* need connection parameters to the master because we can detect
|
||||
* the master in repl_nodes
|
||||
*/
|
||||
if (runtime_options.host[0] || runtime_options.masterport[0] ||
|
||||
runtime_options.username[0] || runtime_options.dbname[0])
|
||||
{
|
||||
error_list_append(_("master connection parameters not required when executing STANDBY UNREGISTER"));
|
||||
}
|
||||
if (runtime_options.dest_dir[0])
|
||||
{
|
||||
error_list_append(_("destination directory not required when executing STANDBY UNREGISTER"));
|
||||
}
|
||||
break;
|
||||
case STANDBY_PROMOTE:
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user