Skip to content

Commit 6ffac11

Browse files
committed
replication: allow to pass instance name as bootstrap_leader
Make it possible to specify the bootstrap leader via an instance name in addition to its URI and UUID. While I'm at it, change the argument order of box_check_node_name() to comply with box_check_uuid/uri/uri_set(). Closes tarantool#8539 @TarantoolBot document Title: `box.cfg.bootstrap_leader` accepts instance names now The option `box.cfg.bootstrap_leader`, which specifies the desired bootstrap leader when bootstrap_strategy is "config" now accepts instance names. For example, this is a valid config without replication: ```lua box.cfg{ instance_name = 'main-server', bootstrap_strategy = 'config', bootstrap_leader = 'main-server' } ``` When `box.cfg` contains some entries in `replication`, the node will bootstrap from the node which has the instance name specified in `box.cfg.bootstrap_leader`. This is an addition to tarantool/doc#3432
1 parent 3c91ad5 commit 6ffac11

File tree

5 files changed

+71
-16
lines changed

5 files changed

+71
-16
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## feature/replication
2+
3+
* Added the ability to set the `bootstrap_leader` configuration option to the
4+
instance name of the desired bootstrap leader:
5+
```lua
6+
box.cfg{
7+
bootstrap_strategy = 'config',
8+
bootstrap_leader = 'leader-name',
9+
replication = {
10+
...
11+
},
12+
...
13+
}
14+
```
15+
(gh-7999, gh-8539).

src/box/box.cc

+17-10
Original file line numberDiff line numberDiff line change
@@ -1326,7 +1326,7 @@ box_check_instance_uuid(struct tt_uuid *uuid)
13261326

13271327
/** Fetch an optional node name from the config. */
13281328
static int
1329-
box_check_node_name(const char *cfg_name, char *out)
1329+
box_check_node_name(char *out, const char *cfg_name, bool set_diag)
13301330
{
13311331
const char *name = cfg_gets(cfg_name);
13321332
if (name == NULL) {
@@ -1335,8 +1335,10 @@ box_check_node_name(const char *cfg_name, char *out)
13351335
}
13361336
/* Nil name is allowed as Lua box.NULL or nil. Not as "". */
13371337
if (!node_name_is_valid(name)) {
1338-
diag_set(ClientError, ER_CFG, cfg_name,
1339-
"expected a valid name");
1338+
if (set_diag) {
1339+
diag_set(ClientError, ER_CFG, cfg_name,
1340+
"expected a valid name");
1341+
}
13401342
return -1;
13411343
}
13421344
strlcpy(out, name, NODE_NAME_SIZE_MAX);
@@ -1346,7 +1348,7 @@ box_check_node_name(const char *cfg_name, char *out)
13461348
static int
13471349
box_check_instance_name(char *out)
13481350
{
1349-
return box_check_node_name("instance_name", out);
1351+
return box_check_node_name(out, "instance_name", true);
13501352
}
13511353

13521354
static int
@@ -1357,10 +1359,11 @@ box_check_replicaset_uuid(struct tt_uuid *uuid)
13571359

13581360
/** Check bootstrap_leader option validity. */
13591361
static int
1360-
box_check_bootstrap_leader(struct uri *uri, struct tt_uuid *uuid)
1362+
box_check_bootstrap_leader(struct uri *uri, struct tt_uuid *uuid, char *name)
13611363
{
13621364
*uuid = uuid_nil;
13631365
uri_create(uri, NULL);
1366+
*name = '\0';
13641367
const char *source = cfg_gets("bootstrap_leader");
13651368
enum bootstrap_strategy strategy = box_check_bootstrap_strategy();
13661369
if (strategy != BOOTSTRAP_STRATEGY_CONFIG) {
@@ -1383,21 +1386,23 @@ box_check_bootstrap_leader(struct uri *uri, struct tt_uuid *uuid)
13831386
/* Not a uri. Try uuid then. */
13841387
if (box_check_uuid(uuid, "bootstrap_leader", false) == 0)
13851388
return 0;
1389+
if (box_check_node_name(name, "bootstrap_leader", false) == 0)
1390+
return 0;
13861391
diag_set(ClientError, ER_CFG, "bootstrap_leader",
1387-
"the value must be either a uri or a uuid");
1392+
"the value must be either a uri, a uuid or a name");
13881393
return -1;
13891394
}
13901395

13911396
static int
13921397
box_check_replicaset_name(char *out)
13931398
{
1394-
return box_check_node_name("replicaset_name", out);
1399+
return box_check_node_name(out, "replicaset_name", true);
13951400
}
13961401

13971402
static int
13981403
box_check_cluster_name(char *out)
13991404
{
1400-
return box_check_node_name("cluster_name", out);
1405+
return box_check_node_name(out, "cluster_name", true);
14011406
}
14021407

14031408
static enum wal_mode
@@ -1661,6 +1666,7 @@ box_check_config(void)
16611666
struct tt_uuid uuid;
16621667
struct uri uri;
16631668
struct uri_set uri_set;
1669+
char name[NODE_NAME_SIZE_MAX];
16641670
box_check_say();
16651671
box_check_audit();
16661672
if (box_check_flightrec() != 0)
@@ -1696,7 +1702,7 @@ box_check_config(void)
16961702
box_check_replication_sync_timeout();
16971703
if (box_check_bootstrap_strategy() == BOOTSTRAP_STRATEGY_INVALID)
16981704
diag_raise();
1699-
if (box_check_bootstrap_leader(&uri, &uuid) != 0)
1705+
if (box_check_bootstrap_leader(&uri, &uuid, name) != 0)
17001706
diag_raise();
17011707
uri_destroy(&uri);
17021708
box_check_readahead(cfg_geti("readahead"));
@@ -1878,7 +1884,8 @@ static int
18781884
box_set_bootstrap_leader(void)
18791885
{
18801886
return box_check_bootstrap_leader(&cfg_bootstrap_leader_uri,
1881-
&cfg_bootstrap_leader_uuid);
1887+
&cfg_bootstrap_leader_uuid,
1888+
cfg_bootstrap_leader_name);
18821889
}
18831890

18841891
/** Persist this instance as the bootstrap leader in _schema space. */

src/box/replication.cc

+9-2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ int replication_threads = 1;
6565
bool cfg_replication_anon = true;
6666
struct tt_uuid cfg_bootstrap_leader_uuid;
6767
struct uri cfg_bootstrap_leader_uri;
68+
char cfg_bootstrap_leader_name[NODE_NAME_SIZE_MAX];
6869
char cfg_instance_name[NODE_NAME_SIZE_MAX];
6970

7071
struct replicaset replicaset;
@@ -948,6 +949,10 @@ applier_is_bootstrap_leader(const struct applier *applier)
948949
{
949950
assert(!tt_uuid_is_nil(&applier->uuid));
950951
if (bootstrap_strategy == BOOTSTRAP_STRATEGY_CONFIG) {
952+
if (*cfg_bootstrap_leader_name != '\0') {
953+
return strcmp(applier->ballot.instance_name,
954+
cfg_bootstrap_leader_name) == 0;
955+
}
951956
if (!tt_uuid_is_nil(&cfg_bootstrap_leader_uuid)) {
952957
return tt_uuid_is_equal(&applier->uuid,
953958
&cfg_bootstrap_leader_uuid);
@@ -1448,8 +1453,10 @@ replicaset_find_join_master_cfg(void)
14481453
if (applier_is_bootstrap_leader(applier))
14491454
leader = replica;
14501455
}
1451-
if (leader == NULL && !tt_uuid_is_equal(&cfg_bootstrap_leader_uuid,
1452-
&INSTANCE_UUID)) {
1456+
if (leader == NULL &&
1457+
!tt_uuid_is_equal(&cfg_bootstrap_leader_uuid, &INSTANCE_UUID) &&
1458+
(strcmp(cfg_bootstrap_leader_name, cfg_instance_name) != 0 ||
1459+
*cfg_bootstrap_leader_name == '\0')) {
14531460
tnt_raise(ClientError, ER_CFG, "bootstrap_leader",
14541461
"failed to connect to the bootstrap leader");
14551462
}

src/box/replication.h

+6
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ extern struct tt_uuid cfg_bootstrap_leader_uuid;
137137
*/
138138
extern struct uri cfg_bootstrap_leader_uri;
139139

140+
/**
141+
* The name of the bootstrap leader configured via the bootstrap_leader
142+
* configuration option.
143+
*/
144+
extern char cfg_bootstrap_leader_name[];
145+
140146
/**
141147
* Configured name of this instance. Might be different from the actual name if
142148
* the configuration is not fully applied yet.

test/replication-luatest/bootstrap_strategy_test.lua

+24-4
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,26 @@ g_config.test_uuid = function(cg)
234234
end)
235235
end
236236

237-
g_config.after_test('test_uuid', function(cg)
238-
cg.server1:stop()
237+
g_config.before_test('test_name', function(cg)
238+
cg.replica_set = replica_set:new{}
239+
cg.server1 = cg.replica_set:build_and_add_server{
240+
alias = 'server1',
241+
box_cfg = {
242+
bootstrap_strategy = 'config',
243+
bootstrap_leader = 'server1name',
244+
instance_name = 'server1name',
245+
replication = nil,
246+
},
247+
}
239248
end)
240249

250+
g_config.test_name = function(cg)
251+
cg.replica_set:start()
252+
t.helpers.retrying({}, cg.server1.exec, cg.server1, function()
253+
t.assert_equals(box.info.status, 'running', 'The server is running')
254+
end)
255+
end
256+
241257
g_config.before_test('test_replication_without_bootstrap_leader', function(cg)
242258
cg.replica_set = replica_set:new{}
243259
cg.server1 = cg.replica_set:build_and_add_server{
@@ -335,6 +351,7 @@ end)
335351
local g_config_success = t.group('gh-7999-bootstrap-strategy-config-success', {
336352
{leader = 'server3'},
337353
{leader = uuid3},
354+
{leader = 'server3name'},
338355
})
339356

340357
g_config_success.after_each(function(cg)
@@ -354,6 +371,7 @@ g_config_success.before_test('test_correct_bootstrap_leader', function(cg)
354371
bootstrap_strategy = 'config',
355372
bootstrap_leader = bootstrap_leader,
356373
instance_uuid = uuid1,
374+
instance_name = 'server1name',
357375
replication = {
358376
server.build_listen_uri('server1', cg.replica_set.id),
359377
server.build_listen_uri('server2', cg.replica_set_a.id),
@@ -367,13 +385,15 @@ g_config_success.before_test('test_correct_bootstrap_leader', function(cg)
367385
box_cfg = {
368386
replicaset_uuid = uuida,
369387
instance_uuid = uuid2,
388+
instance_name = 'server2name',
370389
}
371390
}
372391
cg.server3 = cg.replica_set_b:build_and_add_server{
373392
alias = 'server3',
374393
box_cfg = {
375394
replicaset_uuid = uuidb,
376395
instance_uuid = uuid3,
396+
instance_name = 'server3name',
377397
},
378398
}
379399
end)
@@ -418,6 +438,7 @@ g_config_success.before_test('test_wait_only_for_leader', function(cg)
418438
box_cfg = {
419439
replicaset_uuid = uuidb,
420440
instance_uuid = uuid3,
441+
instance_name = 'server3name',
421442
},
422443
}
423444
end)
@@ -450,8 +471,7 @@ g_config_fail.test_bad_uri_or_uuid = function(cg)
450471
{}, -- empty table.
451472
{'a'}, -- non-empty table.
452473
{3301},
453-
'abracadabra', -- neither a URI or a UUID.
454-
'z2345678-1234-1234-1234-12345678', -- not a UUID.
474+
'1z345678-1234-1234-1234-12345678', -- not a UUID or a name.
455475
}
456476
local errmsg = "Incorrect value for option 'bootstrap_leader':"
457477
local logfile = fio.pathjoin(cfg_failure.workdir, 'cfg_failure.log')

0 commit comments

Comments
 (0)