From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id E3C7E4696C1 for ; Mon, 25 Nov 2019 14:50:14 +0300 (MSK) From: Ilya Kosarev Date: Mon, 25 Nov 2019 14:50:08 +0300 Message-Id: <1028342fcdb89235a219e1c48a5ed24a00ea9d24.1574681299.git.i.kosarev@tarantool.org> In-Reply-To: References: In-Reply-To: References: Subject: [Tarantool-patches] [PATCH v3 3/4] replication: make anon replicas iteration safe List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org In replicaset_follow we iterate anon replicas list: list of replicas that haven't received an UUID. In case of successful connect replica link is being removed from anon list. If it happens immediately, without yield in applier, iteration breaks. Now it is fixed by rlist_foreach_entry_safe instead of common rlist_foreach_entry. Relevant test case is added. Part of #4586 Closes #4576 Closes #4440 --- src/box/replication.cc | 3 +- .../box_set_replication_stress.result | 38 +++++++++++++++++++ .../box_set_replication_stress.test.lua | 17 +++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 test/replication/box_set_replication_stress.result create mode 100644 test/replication/box_set_replication_stress.test.lua diff --git a/src/box/replication.cc b/src/box/replication.cc index f15e51f4d..81f19aa07 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -802,7 +802,8 @@ replicaset_follow(void) if (replica->applier != NULL) applier_resume(replica->applier); } - rlist_foreach_entry(replica, &replicaset.anon, in_anon) { + struct replica *tmp; + rlist_foreach_entry_safe(replica, &replicaset.anon, in_anon, tmp) { /* Restart appliers that failed to connect. */ applier_start(replica->applier); } diff --git a/test/replication/box_set_replication_stress.result b/test/replication/box_set_replication_stress.result new file mode 100644 index 000000000..e683c0643 --- /dev/null +++ b/test/replication/box_set_replication_stress.result @@ -0,0 +1,38 @@ +-- test-run result file version 2 +test_run = require('test_run').new() + | --- + | ... +SERVERS = {'master_quorum1', 'master_quorum2'} + | --- + | ... + +-- Deploy a cluster. +test_run:create_cluster(SERVERS) + | --- + | ... +test_run:wait_fullmesh(SERVERS) + | --- + | ... + +test_run:cmd("switch master_quorum1") + | --- + | - true + | ... +repl = box.cfg.replication + | --- + | ... +for i = 1, 1000 do \ + box.cfg{replication = ""} \ + box.cfg{replication = repl} \ +end + | --- + | ... +test_run:cmd("switch default") + | --- + | - true + | ... + +-- Cleanup. +test_run:drop_cluster(SERVERS) + | --- + | ... diff --git a/test/replication/box_set_replication_stress.test.lua b/test/replication/box_set_replication_stress.test.lua new file mode 100644 index 000000000..407e91e0f --- /dev/null +++ b/test/replication/box_set_replication_stress.test.lua @@ -0,0 +1,17 @@ +test_run = require('test_run').new() +SERVERS = {'master_quorum1', 'master_quorum2'} + +-- Deploy a cluster. +test_run:create_cluster(SERVERS) +test_run:wait_fullmesh(SERVERS) + +test_run:cmd("switch master_quorum1") +repl = box.cfg.replication +for i = 1, 1000 do \ + box.cfg{replication = ""} \ + box.cfg{replication = repl} \ +end +test_run:cmd("switch default") + +-- Cleanup. +test_run:drop_cluster(SERVERS) -- 2.17.1