diff --git a/src/box/replication.cc b/src/box/replication.cc index 6fcc56fe372703164b50a6f7ccbf4913a85196e1..ee102a5978cf2cf001d6d3feff9061bec8af2b7f 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -659,6 +659,20 @@ replicaset_connect(struct applier **appliers, int count, } while (state.connected < count) { + /* + * After a quorum is reached, it is considered + * enough to proceed. Except if a connection is + * critical. + * Connection *is* critical even with 0 quorum + * when the instance starts first time and needs + * to choose replicaset UUID, fill _cluster, etc. + * If 0 quorum allowed to return immediately even + * at first start, then it would be impossible to + * bootstrap a replicaset - all nodes would start + * immediately and choose different cluster UUIDs. + */ + if (state.connected >= quorum && !connect_quorum) + break; double wait_start = ev_monotonic_now(loop()); if (fiber_cond_wait_timeout(&state.wakeup, timeout) != 0) break; diff --git a/test/replication/misc.result b/test/replication/misc.result index ae72ce3e444b40b63271bf721f8d7aa02c6a4d0b..3905cc49edc891a00ad5eb251194c73c9c607b3e 100644 --- a/test/replication/misc.result +++ b/test/replication/misc.result @@ -818,12 +818,33 @@ box.info.ro --- - false ... -box.cfg{replication=""} +-- +-- gh-3760: replication quorum 0 on reconfiguration should return +-- from box.cfg immediately. +-- +replication = box.cfg.replication +--- +... +box.cfg{ \ + replication = {}, \ + replication_connect_quorum = 0, \ + replication_connect_timeout = 1000000 \ +} --- ... -box.cfg{replication_connect_timeout=replication_connect_timeout} +-- The call below would hang, if quorum 0 is ignored, or checked +-- too late. +box.cfg{replication = {'localhost:12345'}} --- ... -box.cfg{replication_connect_quorum=replication_connect_quorum} +box.info.status +--- +- running +... +box.cfg{ \ + replication = replication, \ + replication_connect_quorum = replication_connect_quorum, \ + replication_connect_timeout = replication_connect_timeout \ +} --- ... diff --git a/test/replication/misc.test.lua b/test/replication/misc.test.lua index 16e7e9e42eaec7b74ad103acc90b4a2d12cf49be..696564f94ae066f9cdde2b59730627ffcd935cca 100644 --- a/test/replication/misc.test.lua +++ b/test/replication/misc.test.lua @@ -327,8 +327,22 @@ box.cfg{replication_connect_quorum=1} box.info.status box.info.ro -box.cfg{replication=""} - - -box.cfg{replication_connect_timeout=replication_connect_timeout} -box.cfg{replication_connect_quorum=replication_connect_quorum} +-- +-- gh-3760: replication quorum 0 on reconfiguration should return +-- from box.cfg immediately. +-- +replication = box.cfg.replication +box.cfg{ \ + replication = {}, \ + replication_connect_quorum = 0, \ + replication_connect_timeout = 1000000 \ +} +-- The call below would hang, if quorum 0 is ignored, or checked +-- too late. +box.cfg{replication = {'localhost:12345'}} +box.info.status +box.cfg{ \ + replication = replication, \ + replication_connect_quorum = replication_connect_quorum, \ + replication_connect_timeout = replication_connect_timeout \ +}