diff --git a/src/box/alter.cc b/src/box/alter.cc index 59527c5ec7a833d68a892bcea2fa71f3fc5d8a51..191e17e255341921b9d0da8cb03ecf3fe06eb1e5 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -4248,6 +4248,22 @@ on_replace_dd_cluster(struct trigger *trigger, void *event) return -1; if (replica_check_id(replica_id) != 0) return -1; + /* + * It's okay to update the instance id (drop, then insert) while + * it is joining to a cluster as long as the id is set by the + * time bootstrap is complete, which is checked in box_cfg() + * anyway. + * + * For example, the replica could be deleted from the _cluster + * space on the master manually before rebootstrap, in which + * case it will replay this operation during the final join + * stage. + */ + if (!replicaset.is_joining && replica_id == instance_id) { + diag_set(ClientError, ER_LOCAL_INSTANCE_ID_IS_READ_ONLY, + (unsigned)replica_id); + return -1; + } tt_uuid replica_uuid; if (tuple_field_uuid(old_tuple, BOX_CLUSTER_FIELD_UUID, &replica_uuid) != 0) diff --git a/src/box/replication.cc b/src/box/replication.cc index 389b8b214adba7e83637079586681ec0b122416e..b28bf8519d5cb3d90b4da26e5b1f1554f24c69e0 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -232,21 +232,6 @@ replica_check_id(uint32_t replica_id) (unsigned) replica_id); return -1; } - /* - * It's okay to update the instance id while it is joining to - * a cluster as long as the id is set by the time bootstrap is - * complete, which is checked in box_cfg() anyway. - * - * For example, the replica could be deleted from the _cluster - * space on the master manually before rebootstrap, in which - * case it will replay this operation during the final join - * stage. - */ - if (!replicaset.is_joining && replica_id == instance_id) { - diag_set(ClientError, ER_LOCAL_INSTANCE_ID_IS_READ_ONLY, - (unsigned) replica_id); - return -1; - } return 0; } @@ -380,7 +365,6 @@ replica_clear_id(struct replica *replica) --replicaset.registered_count; gc_delay_unref(); if (replica->id == instance_id) { - /* See replica_check_id(). */ assert(replicaset.is_joining); instance_id = REPLICA_ID_NIL; box_broadcast_id(); diff --git a/test/replication-py/cluster.result b/test/replication-py/cluster.result index f68a6af7c69af7b164ad92527b9f920e01d7574d..b96940e698d31174eecf0408f6850b363d5eace2 100644 --- a/test/replication-py/cluster.result +++ b/test/replication-py/cluster.result @@ -27,14 +27,18 @@ gh-434: Assertion if replace _cluster tuple for local server ------------------------------------------------------------- box.space._cluster:replace{1, require('uuid').NULL:str()} --- -- error: The local instance id 1 is read-only +- error: 'Invalid UUID: 00000000-0000-0000-0000-000000000000' ... box.space._cluster:replace{1, require('uuid').str()} --- -- error: The local instance id 1 is read-only +- error: Space _cluster does not support updates of instance uuid ... box.space._cluster:update(1, {{'=', 3, 'test'}}) --- +- [1, '<master uuid>', 'test'] +... +box.space._cluster:delete(1) +--- - error: The local instance id 1 is read-only ... ------------------------------------------------------------- diff --git a/test/replication-py/cluster.test.py b/test/replication-py/cluster.test.py index ee915b591e02d89d786afdd2c99d33a349b5384a..1f36511ede1243780b5c1548de1ce38872bd9e9f 100644 --- a/test/replication-py/cluster.test.py +++ b/test/replication-py/cluster.test.py @@ -89,6 +89,9 @@ server.admin("box.space._cluster:replace{1, require('uuid').str()}") # Update of tail is OK server.admin("box.space._cluster:update(1, {{'=', 3, 'test'}})") +# Self-delete is not ok. +server.admin("box.space._cluster:delete(1)") + print("-------------------------------------------------------------") print("gh-1140: Assertion if replace _cluster tuple for remote server") print("-------------------------------------------------------------")