Skip to content

Commit

Permalink
config: don't try to persist anon replica name
Browse files Browse the repository at this point in the history
The commit effectively enables support of anonymous replicas in the
declarative configuration. It has several caveats (see the changelog
entry), which will be resolved in the following commits of the patchset.

An attempt to persist an instance name of an anonymous replica can't be
successful, because it has no entry in `_cluster` system space. Such an
attempt leads to ER_INSTANCE_NAME_MISMATCH error.

This commit patches the configuration applying logic to skip attempt to
set `box.cfg({instance_name = <...>})` if the instance is configured as
an anonymous replica using `replication.anon: true` option.

Part of tarantool#9432

NO_DOC=replication.anon option is already documented in the scope of
       tarantool/doc#3851. The bugfix
       shouldn't affect the documentation pages much, however related
       constraints are summarized in a documentation request in the last
       commit of the series.
  • Loading branch information
Totktonada committed Dec 5, 2023
1 parent a5596cf commit 05784df
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
24 changes: 24 additions & 0 deletions changelogs/unreleased/config-anonymous-replica.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## bugfix/config

* Support `replication.anon` option (gh-9432).

There are caveats that are not resolved yet:

* An anonymous replica shouldn't be used as an upstream for non-anonymous
replica.
* An anonymous replica possibly shouldn't be used as an upstream for other
anonymous replicas by default.
* An anonymous replica shouldn't be chosen as a bootstrap leader in
`replication.failover: supervised` mode.
* An attempt to configure a replicaset where all instances are anonymous
replicas should lead to an error on config validation, before configuration
applying.
* An attempt to configure an anonymous replica in read-write mode (using
`database.mode` or `<replicaset>.leader`) should lead to an error on config
validation, before configuration applying.
* An attempt to configure an anonymous replica with
`replication.election_mode` != `off` should lead to an error on config
validation, before configuration applying.
* An anonymous replica can't be bootstrapped from a replicaset, where all the
instance are in read-only mode, however there are no technical problems
there (just too tight validation).
7 changes: 6 additions & 1 deletion src/box/lua/config/applier/box_cfg.lua
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ local function apply(config)

local failover = configdata:get('replication.failover',
{use_default = true})
local is_anon = configdata:get('replication.anon', {use_default = true})

-- Read-only or read-write?
if failover == 'off' then
Expand Down Expand Up @@ -520,8 +521,12 @@ local function apply(config)

-- Names are applied only if they're already in snap file.
-- Otherwise, master must apply names after box.cfg asynchronously.
--
-- Note: an anonymous replica has no an entry in the _cluster
-- system space, so it can't have a persistent instance name.
-- It is never returned by :missing_names().
local missing_names = configdata:missing_names()
if not missing_names._peers[names.instance_name] then
if not is_anon and not missing_names._peers[names.instance_name] then
box_cfg.instance_name = names.instance_name
end
if not missing_names[names.replicaset_name] then
Expand Down
61 changes: 61 additions & 0 deletions test/config-luatest/anonymous_replica_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
local t = require('luatest')
local cbuilder = require('test.config-luatest.cbuilder')
local replicaset = require('test.config-luatest.replicaset')

local g = t.group()

g.before_all(replicaset.init)
g.after_each(replicaset.drop)
g.after_all(replicaset.clean)

-- Verify that an anonymous replica can be started and joined to
-- a replicaset.
--
-- This test excludes the `replication.peers` autoconstruction
-- logic by defining the option on its own. This automatic
-- construction is verified in a separate test case (TODO).
g.test_basic = function(g)
-- One master, two replicas, two anonymous replicas.
local config = cbuilder.new()
:set_replicaset_option('replication.peers', {
'replicator:secret@unix/:./instance-001.iproto',
'replicator:secret@unix/:./instance-002.iproto',
'replicator:secret@unix/:./instance-003.iproto',
})
:add_instance('instance-001', {
database = {
mode = 'rw',
},
})
:add_instance('instance-002', {})
:add_instance('instance-003', {})
:add_instance('instance-004', {
replication = {
anon = true,
},
})
:add_instance('instance-005', {
replication = {
anon = true,
},
})
:config()

local replicaset = replicaset.new(g, config)
replicaset:start()

-- Verify that all the instances are healthy.
replicaset:each(function(server)
server:exec(function()
t.assert_equals(box.info.status, 'running')
end)
end)

-- Verify that the anonymous replicas are actually anonymous.
replicaset['instance-004']:exec(function()
t.assert_equals(box.info.id, 0)
end)
replicaset['instance-005']:exec(function()
t.assert_equals(box.info.id, 0)
end)
end

0 comments on commit 05784df

Please sign in to comment.