Skip to content

Commit

Permalink
storage: introduce name identification
Browse files Browse the repository at this point in the history
This commit allows storage to use named config identification.

Part of #426

@TarantoolBot document
Title: vshard: vshard.storage.cfg argument change

vshard.storage.cfg(cfg, instance_id)

Configure the database and start sharding for the specified storage
instance. `istance_id` depends on `identification_mode` used in config.
If it's 'uuid_as_key', which is default, then UUID must be used.
Otherwise - instance_name.

Parameters:
    cfg – a storage configuration
    instance_id – UUID or name of the instance
  • Loading branch information
Serpentian authored and Gerold103 committed Dec 19, 2023
1 parent 9ca078e commit 4c9cc51
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 41 deletions.
105 changes: 105 additions & 0 deletions test/storage-luatest/persistent_names_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
local t = require('luatest')
local vtest = require('test.luatest_helpers.vtest')
local vutil = require('vshard.util')

local test_group = t.group('storage')

local cfg_template = {
sharding = {
replicaset_1 = {
replicas = {
replica_1_a = {
master = true,
},
},
},
replicaset_2 = {
replicas = {
replica_2_a = {
master = true,
},
},
},
},
bucket_count = 10,
replication_timeout = 0.1,
identification_mode = 'name_as_key',
}
local global_cfg

test_group.before_all(function(g)
-- Even cluster bootstrap can be done only on Tarantool >= 3.0.0.
-- No need to add run_only_if for every test. This skips them all.
t.run_only_if(vutil.feature.persistent_names)
global_cfg = vtest.config_new(cfg_template)

vtest.cluster_new(g, global_cfg)
vtest.cluster_bootstrap(g, global_cfg)
vtest.cluster_rebalancer_disable(g)
end)

test_group.after_all(function(g)
g.cluster:drop()
end)

--
-- Test, that all names are properly set after cluster bootstrap.
--
test_group.test_basic = function(g)
local rs_name = g.replica_1_a:replicaset_name()
local name = g.replica_1_a:instance_name()
t.assert_equals(rs_name, 'replicaset_1')
t.assert_equals(name, 'replica_1_a')
rs_name = g.replica_2_a:replicaset_name()
name = g.replica_2_a:instance_name()
t.assert_equals(rs_name, 'replicaset_2')
t.assert_equals(name, 'replica_2_a')
end

--
-- Test named config to UUID config switch.
--
test_group.test_switch_to_uuid = function(g)
-- Make UUID indexed config.
local new_cfg = table.deepcopy(global_cfg)
local uuid_rs_1 = g.replica_1_a:replicaset_uuid()
local uuid_1 = g.replica_1_a:instance_uuid()
local uuid_rs_2 = g.replica_2_a:replicaset_uuid()
local uuid_2 = g.replica_2_a:instance_uuid()
new_cfg.identification_mode = 'uuid_as_key'
local sharding = new_cfg.sharding
sharding[uuid_rs_1] = sharding.replicaset_1
sharding[uuid_rs_2] = sharding.replicaset_2
sharding.replicaset_1 = nil
sharding.replicaset_2 = nil
sharding[uuid_rs_1].replicas[uuid_1] =
sharding[uuid_rs_1].replicas.replica_1_a
sharding[uuid_rs_2].replicas[uuid_2] =
sharding[uuid_rs_2].replicas.replica_2_a
sharding[uuid_rs_1].replicas.replica_1_a = nil
sharding[uuid_rs_2].replicas.replica_2_a = nil

-- Send bucket on UUID identification.
vtest.cluster_cfg(g, new_cfg)
local bid = g.replica_1_a:exec(function(uuid)
local bid = _G.get_first_bucket()
local ok, err = ivshard.storage.bucket_send(
bid, uuid, {timeout = _G.iwait_timeout})
ilt.assert_equals(err, nil)
ilt.assert(ok)
_G.bucket_recovery_wait()
_G.bucket_gc_wait()
return bid
end, {uuid_rs_2})

-- Send it back on name identification.
vtest.cluster_cfg(g, global_cfg)
g.replica_2_a:exec(function(bid, name)
local ok, err = ivshard.storage.bucket_send(
bid, name, {timeout = _G.iwait_timeout})
ilt.assert_equals(err, nil)
ilt.assert(ok)
_G.bucket_recovery_wait()
_G.bucket_gc_wait()
end, {bid, g.replica_1_a:replicaset_name()})
end
76 changes: 76 additions & 0 deletions test/storage-luatest/storage_1_1_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,79 @@ test_group.test_noactivity_timeout_for_explicit_master = function(g)
_G.bucket_gc_wait()
end, {g.replica_1_a:replicaset_uuid(), bid})
end

test_group.test_named_config_identification = function(g)
t.run_only_if(vutil.feature.persistent_names)
local new_cfg_template = table.deepcopy(cfg_template)
new_cfg_template.identification_mode = 'name_as_key'
new_cfg_template.sharding['replicaset_1'] = new_cfg_template.sharding[1]
new_cfg_template.sharding['replicaset_2'] = new_cfg_template.sharding[2]
new_cfg_template.sharding[1] = nil
new_cfg_template.sharding[2] = nil
local new_global_cfg = vtest.config_new(new_cfg_template)

-- Attempt to configure with named config without name set causes error.
g.replica_1_a:exec(function(cfg)
ilt.assert_error_msg_contains('Instance name mismatch',
ivshard.storage.cfg, cfg, 'replica_1_a')
end, {new_global_cfg})

-- Set names on all replicas.
g.replica_1_a:exec(function()
box.cfg{instance_name = 'replica_1_a', replicaset_name = 'replicaset_1'}
end)
g.replica_2_a:exec(function()
box.cfg{instance_name = 'replica_2_a', replicaset_name = 'replicaset_2'}
end)

-- Check, that UUIDs are validated, when named config is used.
local rs_1_cfg = new_global_cfg.sharding.replicaset_1
local replica_1_a_cfg = rs_1_cfg.replicas.replica_1_a
replica_1_a_cfg.uuid = g.replica_2_a:instance_uuid()
g.replica_1_a:exec(function(cfg)
ilt.assert_error_msg_contains('Instance UUID mismatch',
ivshard.storage.cfg, cfg, 'replica_1_a')
end, {new_global_cfg})
-- The correct UUID should be OK.
replica_1_a_cfg.uuid = g.replica_1_a:instance_uuid()

-- Now the config can be finally applied.
vtest.cluster_cfg(g, new_global_cfg)

-- Test, that sending by name works properly
local rs_name_2 = g.replica_2_a:replicaset_name()
t.assert_equals(rs_name_2, 'replicaset_2')
local bid = g.replica_1_a:exec(function(name)
local bid = _G.get_first_bucket()
local ok, err = ivshard.storage.bucket_send(
bid, name, {timeout = _G.iwait_timeout})
ilt.assert_equals(err, nil)
ilt.assert(ok)
return bid
end, {rs_name_2})

-- Test, that rebalancer is also ok.
vtest.cluster_rebalancer_enable(g)
g.replica_1_a:exec(function(bid)
local internal = ivshard.storage.internal
ivtest.service_wait_for_new_ok(internal.rebalancer_service,
{on_yield = ivshard.storage.rebalancer_wakeup})

-- Cleanup
_G.bucket_recovery_wait()
_G.bucket_gc_wait()
ilt.assert_equals(ivshard.storage.buckets_info()[bid], nil)
end, {bid})

g.replica_2_a:exec(function(bid)
_G.bucket_recovery_wait()
_G.bucket_gc_wait()
local buckets_info = ivshard.storage.buckets_info()
ilt.assert_not_equals(buckets_info[bid], nil)
ilt.assert_equals(buckets_info[bid].status, 'active')
end, {bid})

vtest.cluster_rebalancer_disable(g)
-- Back to UUID identification.
vtest.cluster_cfg(g, global_cfg)
end
14 changes: 7 additions & 7 deletions test/unit/rebalancer.result
Original file line number Diff line number Diff line change
Expand Up @@ -1078,9 +1078,9 @@ d
map:
uuid:
bucket_count: 0
id: uuid
progress: 0
is_throttle_warned: false
uuid: uuid
need_to_send: 15
...
d = dispenser.create({uuid1 = 5, uuid2 = 5})
Expand All @@ -1099,13 +1099,13 @@ u, d
prev: &1
bucket_count: 5
next: *0
id: uuid1
progress: 0
is_throttle_warned: false
uuid: uuid1
need_to_send: 5
id: uuid2
progress: 0
is_throttle_warned: false
uuid: uuid2
need_to_send: 5
first: *1
map:
Expand All @@ -1124,13 +1124,13 @@ d
prev: &1
bucket_count: 5
next: *0
id: uuid1
progress: 0
is_throttle_warned: false
uuid: uuid1
need_to_send: 5
id: uuid2
progress: 0
is_throttle_warned: false
uuid: uuid2
need_to_send: 5
first: *1
map:
Expand All @@ -1150,13 +1150,13 @@ d
prev: &1
bucket_count: 5
next: *0
id: uuid1
progress: 0
is_throttle_warned: false
uuid: uuid1
need_to_send: 5
id: uuid2
progress: 0
is_throttle_warned: true
uuid: uuid2
need_to_send: 5
first: *1
map:
Expand Down
Loading

0 comments on commit 4c9cc51

Please sign in to comment.