diff --git a/src/Coordination/InMemoryStateManager.cpp b/src/Coordination/InMemoryStateManager.cpp index d90c7e46f0d..a6db3271bc1 100644 --- a/src/Coordination/InMemoryStateManager.cpp +++ b/src/Coordination/InMemoryStateManager.cpp @@ -28,6 +28,9 @@ InMemoryStateManager::InMemoryStateManager( int port = config.getInt(full_prefix + ".port"); bool can_become_leader = config.getBool(full_prefix + ".can_become_leader", true); int32_t priority = config.getInt(full_prefix + ".priority", 1); + bool start_as_follower = config.getBool(full_prefix + ".start_as_follower", false); + if (start_as_follower) + start_as_follower_servers.insert(server_id); auto endpoint = hostname + ":" + std::to_string(port); auto peer_config = nuraft::cs_new(server_id, 0, endpoint, "", !can_become_leader, priority); @@ -41,6 +44,9 @@ InMemoryStateManager::InMemoryStateManager( } if (!my_server_config) throw Exception(ErrorCodes::RAFT_ERROR, "Our server id {} not found in raft_configuration section"); + + if (start_as_follower_servers.size() == cluster_config->get_servers().size()) + throw Exception(ErrorCodes::RAFT_ERROR, "At least one of servers should be able to start as leader (without )"); } void InMemoryStateManager::save_config(const nuraft::cluster_config & config) diff --git a/src/Coordination/InMemoryStateManager.h b/src/Coordination/InMemoryStateManager.h index b48b5188f36..a4537602b36 100644 --- a/src/Coordination/InMemoryStateManager.h +++ b/src/Coordination/InMemoryStateManager.h @@ -35,9 +35,15 @@ public: int getPort() const { return my_port; } + bool shouldStartAsFollower() const + { + return start_as_follower_servers.count(my_server_id); + } + private: int my_server_id; int my_port; + std::unordered_set start_as_follower_servers; nuraft::ptr log_store; nuraft::ptr my_server_config; nuraft::ptr cluster_config; diff --git a/src/Coordination/NuKeeperServer.cpp b/src/Coordination/NuKeeperServer.cpp index c7deebfdb96..7464a06e86f 100644 --- a/src/Coordination/NuKeeperServer.cpp +++ b/src/Coordination/NuKeeperServer.cpp @@ -31,7 +31,7 @@ NuKeeperServer::NuKeeperServer( { } -void NuKeeperServer::startup(bool should_build_quorum) +void NuKeeperServer::startup() { nuraft::raft_params params; params.heart_beat_interval_ = coordination_settings->heart_beat_interval_ms.totalMilliseconds(); @@ -47,7 +47,7 @@ void NuKeeperServer::startup(bool should_build_quorum) nuraft::asio_service::options asio_opts{}; nuraft::raft_server::init_options init_options; - init_options.skip_initial_election_timeout_ = !should_build_quorum; + init_options.skip_initial_election_timeout_ = state_manager->shouldStartAsFollower(); init_options.raft_callback_ = [this] (nuraft::cb_func::Type type, nuraft::cb_func::Param * param) { return callbackFunc(type, param); diff --git a/src/Coordination/NuKeeperServer.h b/src/Coordination/NuKeeperServer.h index a37d4d9127a..a8d269eb9eb 100644 --- a/src/Coordination/NuKeeperServer.h +++ b/src/Coordination/NuKeeperServer.h @@ -43,7 +43,7 @@ public: const Poco::Util::AbstractConfiguration & config, ResponsesQueue & responses_queue_); - void startup(bool should_build_quorum); + void startup(); void putRequest(const NuKeeperStorage::RequestForSession & request); diff --git a/src/Coordination/NuKeeperStorageDispatcher.cpp b/src/Coordination/NuKeeperStorageDispatcher.cpp index 042f0d2ffb9..570087757ad 100644 --- a/src/Coordination/NuKeeperStorageDispatcher.cpp +++ b/src/Coordination/NuKeeperStorageDispatcher.cpp @@ -114,7 +114,7 @@ void NuKeeperStorageDispatcher::initialize(const Poco::Util::AbstractConfigurati try { LOG_DEBUG(log, "Waiting server to initialize"); - server->startup(true); + server->startup(); LOG_DEBUG(log, "Server initialized, waiting for quorum"); server->waitInit(); diff --git a/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper1.xml b/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper1.xml index 3ae44f926d0..4ad76889d1e 100644 --- a/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper1.xml +++ b/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper1.xml @@ -22,6 +22,7 @@ node2 44444 true + true 2 @@ -29,6 +30,7 @@ node3 44444 true + true 1 diff --git a/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper2.xml b/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper2.xml index 7674c755511..a1954a1e639 100644 --- a/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper2.xml +++ b/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper2.xml @@ -22,6 +22,7 @@ node2 44444 true + true 2 @@ -29,6 +30,7 @@ node3 44444 true + true 1 diff --git a/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper3.xml b/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper3.xml index 59dde3bc1b1..88d2358138f 100644 --- a/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper3.xml +++ b/tests/integration/test_testkeeper_multinode/configs/enable_test_keeper3.xml @@ -22,6 +22,7 @@ node2 44444 true + true 2 @@ -29,6 +30,7 @@ node3 44444 true + true 1