Skip to content

Commit

Permalink
config: set names automatically on schema upgrade
Browse files Browse the repository at this point in the history
It's impossible to set names on Tarantool below 3.0.0, as all DDL
is forbidden before schema upgrade.

Let's make names NoOp on schema below Tarantool 3.0.0 and set names
automatically only schema upgrade is done.

Follow-up tarantool#8978

NO_DOC=tarantool/doc#3661
NO_CHANGELOG=following commits
  • Loading branch information
Serpentian committed Oct 12, 2023
1 parent ecaffe4 commit f9e0ecf
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## feature/config

* If Tarantool is configured via a YAML file or etcd, then
instance/replicaset/cluster names are automatically set, when it is possible.
29 changes: 29 additions & 0 deletions src/box/lua/config/applier/box_cfg.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local fiber = require('fiber')
local log = require('internal.config.utils.log')
local instance_config = require('internal.config.instance_config')
local mkversion = require('internal.mkversion')

local function peer_uri(configdata, peer_name)
local iconfig = configdata._peers[peer_name].iconfig_def
Expand Down Expand Up @@ -453,10 +454,17 @@ local function apply_names_cluster_on_replace(old, new)
end
end

local apply_names_schema_upgrade

local function apply_names_f(configdata)
local name = 'config_apply_names'
fiber.self():name(name)

local version = mkversion.get()
if version < mkversion(3, 0, 0) then
apply_names_schema_upgrade:wait()
end

box.ctl.wait_rw()

if table.equals(configdata._missing_names, {}) then
Expand All @@ -476,6 +484,21 @@ local function apply_names_f(configdata)
end
end

local function upgrade_schema_on_replace(old, new)
if old == nil or new == nil then
return
end

local version_3 = mkversion(3, 0, 0)
local old_version = mkversion.from_tuple(old)
local new_version = mkversion.from_tuple(new)
if old_version < version_3 and new_version >= version_3 then
box.on_commit(function()
pcall(apply_names_schema_upgrade.signal, apply_names_schema_upgrade)
end)
end
end

local function post_apply(config)
local configdata = config._configdata
if table.equals(configdata._missing_names, {}) then
Expand All @@ -488,6 +511,12 @@ local function post_apply(config)
box.space._cluster:on_replace(apply_names_cluster_on_replace)
box.space._schema:on_replace(apply_names_schema_on_replace)

apply_names_schema_upgrade = fiber.cond()
local version = mkversion.get()
if version < mkversion(3, 0, 0) then
box.space._schema:on_replace(upgrade_schema_on_replace)
end

local watch
local names = configdata:names()
watch = box.watch('apply_name', function(_, name)
Expand Down
3 changes: 2 additions & 1 deletion src/box/lua/config/configdata.lua
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ local function snapshot_names(snap_path)
end

if body.space_id == space_ids._schema then
if body.tuple[1] == 'replicaset_uuid' then
if body.tuple[1] == 'replicaset_uuid' or
body.tuple[1] == 'cluster' then
replicaset_uuid = body.tuple[2]
elseif body.tuple[1] == 'replicaset_name' then
replicaset_name = body.tuple[2]
Expand Down
Binary file not shown.
16 changes: 16 additions & 0 deletions test/box-luatest/upgrade/2.11.0/replicaset/instance-001/gen.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
box.cfg{
replicaset_uuid = 'cbf06940-0790-498b-948d-042b62cf3d29',
instance_uuid = '8a274925-a26d-47fc-9e1b-af88ce939412',
replication = {3301, 3302},
listen = 3301,
}

box.schema.user.grant('guest', 'super')
box.schema.create_space('test_space')
while not box.info.replication[2] or
not box.info.replication[2].downstream or
box.info.replication[2].downstream.status ~= 'follow' do
require('fiber').yield(0.1)
end
box.snapshot()
os.exit(0)
Binary file not shown.
10 changes: 10 additions & 0 deletions test/box-luatest/upgrade/2.11.0/replicaset/instance-002/gen.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
box.cfg{
replicaset_uuid = 'cbf06940-0790-498b-948d-042b62cf3d29',
instance_uuid = '3de2e3e1-9ebe-4d0d-abb1-26d301b84633',
replication = {3301, 3302},
read_only = true,
listen = 3302,
}

box.snapshot()
os.exit(0)
122 changes: 122 additions & 0 deletions test/config-luatest/upgrade_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
local t = require('luatest')
local treegen = require('test.treegen')
local server = require('test.luatest_helpers.server')
local yaml = require('yaml')
local fun = require('fun')
local fio = require('fio')

local g = t.group('set-names-automatically-on-upgrade')

g.before_all(function(g)
treegen.init(g)

local uuids = {
['replicaset-001'] = 'cbf06940-0790-498b-948d-042b62cf3d29',
['instance-001'] = '8a274925-a26d-47fc-9e1b-af88ce939412',
['instance-002'] = '3de2e3e1-9ebe-4d0d-abb1-26d301b84633'
}

local datadir_prefix = 'test/box-luatest/upgrade/2.11.0/replicaset/'
local datadir_1 = fio.abspath(fio.pathjoin(datadir_prefix, 'instance-001'))
local datadir_2 = fio.abspath(fio.pathjoin(datadir_prefix, 'instance-002'))

local dir = treegen.prepare_directory(g, {}, {})
local workdir_1 = fio.pathjoin(dir, 'instance-001')
local workdir_2 = fio.pathjoin(dir, 'instance-002')

fio.mktree(workdir_1)
fio.mktree(workdir_2)

fio.copytree(datadir_1, workdir_1)
fio.copytree(datadir_2, workdir_2)

local config = {
credentials = {
users = {
guest = {
roles = {'super'},
},
},
},

iproto = {
listen = 'unix/:./{{ instance_name }}.iproto',
},

groups = {
['group-001'] = {
replicasets = {
['replicaset-001'] = {
database = {
replicaset_uuid = uuids['replicaset-001']
},
instances = {
['instance-001'] = {
snapshot = { dir = workdir_1, },
wal = { dir = workdir_1, },
database = {
instance_uuid = uuids['instance-001'],
mode = 'rw',
},
},
['instance-002'] = {
snapshot = { dir = workdir_2, },
wal = { dir = workdir_2, },
database = {
instance_uuid = uuids['instance-002']
},
},
},
},
},
},
},
}

local cfg = yaml.encode(config)
local config_file = treegen.write_script(dir, 'cfg.yaml', cfg)
local opts = {config_file = config_file, chdir = dir}
g.instance_1 = server:new(fun.chain(opts, {alias = 'instance-001'}):tomap())
g.instance_2 = server:new(fun.chain(opts, {alias = 'instance-002'}):tomap())

g.instance_1:start({wait_until_ready = false})
g.instance_2:start({wait_until_ready = false})
t.helpers.retrying({}, function()
g.instance_1:connect_net_box()
g.instance_2:connect_net_box()
end)
end)

g.after_all(function(g)
g.instance_1:drop()
g.instance_2:drop()
treegen.clean(g)
end)

local function assert_before_upgrade()
t.assert_equals(box.space._schema:get{'version'}, {'version', 2, 11, 0})
local info = box.info
t.assert_equals(info.name, nil)
t.assert_equals(info.replicaset.name, nil)
end

local function assert_after_upgrade(instance_name, replicaset_name)
t.assert_equals(box.space._schema:get{'version'}, {'version', 3, 0, 0})
t.helpers.retrying({timeout = 10}, function()
local info = box.info
t.assert_equals(info.name, instance_name)
t.assert_equals(info.replicaset.name, replicaset_name)
end)
end

g.test_upgrade = function()
g.instance_1:exec(assert_before_upgrade)
g.instance_2:exec(assert_before_upgrade)

g.instance_1:exec(function() box.schema.upgrade() end)
g.instance_2:wait_for_vclock_of(g.instance_1)

local rs_name = 'replicaset-001'
g.instance_1:exec(assert_after_upgrade, {g.instance_1.alias, rs_name})
g.instance_2:exec(assert_after_upgrade, {g.instance_2.alias, rs_name})
end

0 comments on commit f9e0ecf

Please sign in to comment.