diff --git a/changelogs/unreleased/replicaset-uuid-update-ban.md b/changelogs/unreleased/replicaset-uuid-update-ban.md new file mode 100644 index 0000000000000000000000000000000000000000..b6e5c69ec1d524a9d47b2334a10365f124c338aa --- /dev/null +++ b/changelogs/unreleased/replicaset-uuid-update-ban.md @@ -0,0 +1,3 @@ +## bugfix/replication + +* Fixed a bug that allowed to change replicaset UUID via `_schema` space. diff --git a/src/box/alter.cc b/src/box/alter.cc index c81f35462a650f858f52c5fff505c22bc769e326..5255abf10a5acd21cfce8410af930ae1dceec42b 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -3978,6 +3978,11 @@ on_replace_dd_schema(struct trigger * /* trigger */, void *event) tt_uuid uu; if (tuple_field_uuid(new_tuple, BOX_SCHEMA_FIELD_VALUE, &uu) != 0) return -1; + if (!tt_uuid_is_nil(&REPLICASET_UUID) && + !tt_uuid_is_equal(&REPLICASET_UUID, &uu)) { + diag_set(ClientError, ER_REPLICASET_UUID_IS_RO); + return -1; + } REPLICASET_UUID = uu; box_broadcast_id(); say_info("cluster uuid %s", tt_uuid_str(&uu)); diff --git a/test/box-luatest/schema_sys_space_test.lua b/test/box-luatest/schema_sys_space_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..f8fde9eded3270b78abea4c09081ce15b018ed91 --- /dev/null +++ b/test/box-luatest/schema_sys_space_test.lua @@ -0,0 +1,26 @@ +local server = require('luatest.server') +local t = require('luatest') +local g = t.group() + +g.before_all = function(lg) + lg.server = server:new({alias = 'master'}) + lg.server:start() +end + +g.after_all = function(lg) + lg.server:drop() +end + +g.test_cluster_uuid_update_ban = function(lg) + lg.server:exec(function() + local uuid = require('uuid') + local _schema = box.space._schema + local msg = "Can't reset replica set UUID" + t.assert_error_msg_contains(msg, _schema.replace, _schema, + {'cluster', uuid.str()}) + t.assert_error_msg_contains(msg, _schema.replace, _schema, + {'cluster', tostring(uuid.NULL)}) + -- Fine to replace with the same value. + _schema:replace{'cluster', box.info.cluster.uuid} + end) +end