From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp53.i.mail.ru (smtp53.i.mail.ru [94.100.177.113]) (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 5217B4696C2 for ; Sun, 24 Nov 2019 00:54:05 +0300 (MSK) From: Ilya Kosarev Date: Sun, 24 Nov 2019 00:53:57 +0300 Message-Id: <64301ef71c1bfb38011bb25b54b5c12a976468ce.1574545667.git.i.kosarev@tarantool.org> In-Reply-To: References: In-Reply-To: References: Subject: [Tarantool-patches] [PATCH v2 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 --- 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 3ccfa8b33..2970d61cf 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -800,7 +800,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