Ensure 'master register --force' can't create more than one active primary node record

This commit is contained in:
Ian Barwick
2015-11-26 10:53:59 +09:00
parent 9ed71d6317
commit 67df082ee9
2 changed files with 21 additions and 7 deletions

View File

@@ -793,6 +793,8 @@ do_master_register(void)
bool schema_exists = false; bool schema_exists = false;
int ret; int ret;
int primary_node_id = UNKNOWN_NODE_ID;
bool record_created; bool record_created;
conn = establish_db_connection(options.conninfo, true); conn = establish_db_connection(options.conninfo, true);
@@ -849,19 +851,29 @@ do_master_register(void)
PQfinish(master_conn); PQfinish(master_conn);
/* XXX we should check if a node with a different ID is registered as begin_transaction(conn);
master, otherwise it would be possible to insert a duplicate record
with --force, which would result in an unwelcome "multi-master" situation /*
* Check if a node with a different ID is registered as primary. This shouldn't
* happen but could do if an existing master was shut down without being
* unregistered.
*/ */
primary_node_id = get_master_node_id(conn, options.cluster_name);
if (primary_node_id != NODE_NOT_FOUND && primary_node_id != options.node)
{
log_err(_("another node with id %i is already registered as master\n"), primary_node_id);
rollback_transaction(conn);
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
/* Delete any existing record for this node if --force set */ /* Delete any existing record for this node if --force set */
if (runtime_options.force) if (runtime_options.force)
{ {
PGresult *res; PGresult *res;
bool node_record_deleted; bool node_record_deleted;
begin_transaction(conn);
res = get_node_record(conn, options.cluster_name, options.node); res = get_node_record(conn, options.cluster_name, options.node);
if (PQntuples(res)) if (PQntuples(res))
{ {
@@ -878,7 +890,6 @@ do_master_register(void)
} }
} }
commit_transaction(conn);
} }
@@ -896,10 +907,13 @@ do_master_register(void)
if (record_created == false) if (record_created == false)
{ {
rollback_transaction(conn);
PQfinish(conn); PQfinish(conn);
exit(ERR_DB_QUERY); exit(ERR_DB_QUERY);
} }
commit_transaction(conn);
/* Log the event */ /* Log the event */
create_event_record(conn, create_event_record(conn,
&options, &options,

View File

@@ -48,7 +48,7 @@
#define AUTOMATIC_FAILOVER 1 #define AUTOMATIC_FAILOVER 1
#define NODE_NOT_FOUND -1 #define NODE_NOT_FOUND -1
#define NO_UPSTREAM_NODE -1 #define NO_UPSTREAM_NODE -1
#define UNKNOWN_NODE_ID -1