Forbid having multiple mains in the cluster (#1727)

This commit is contained in:
Andi 2024-02-16 12:41:15 +01:00 committed by GitHub
parent bfc756c092
commit 3e3224f0a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 22 additions and 0 deletions

View File

@ -206,6 +206,10 @@ auto CoordinatorInstance::SetReplicationInstanceToMain(std::string instance_name
-> SetInstanceToMainCoordinatorStatus {
auto lock = std::lock_guard{coord_instance_lock_};
if (std::ranges::any_of(repl_instances_, &ReplicationInstance::IsMain)) {
return SetInstanceToMainCoordinatorStatus::MAIN_ALREADY_EXISTS;
}
auto const is_new_main = [&instance_name](ReplicationInstance const &instance) {
return instance.InstanceName() == instance_name;
};

View File

@ -39,6 +39,7 @@ enum class UnregisterInstanceCoordinatorStatus : uint8_t {
enum class SetInstanceToMainCoordinatorStatus : uint8_t {
NO_INSTANCE_WITH_NAME,
MAIN_ALREADY_EXISTS,
NOT_COORDINATOR,
SUCCESS,
COULD_NOT_PROMOTE_TO_MAIN,

View File

@ -563,6 +563,8 @@ class CoordQueryHandler final : public query::CoordinatorQueryHandler {
using enum memgraph::coordination::SetInstanceToMainCoordinatorStatus;
case NO_INSTANCE_WITH_NAME:
throw QueryRuntimeException("No instance with such name!");
case MAIN_ALREADY_EXISTS:
throw QueryRuntimeException("Couldn't set instance to main since there is already a main instance in cluster!");
case NOT_COORDINATOR:
throw QueryRuntimeException("SET INSTANCE TO MAIN query can only be run on a coordinator!");
case COULD_NOT_PROMOTE_TO_MAIN:

View File

@ -515,5 +515,20 @@ def test_automatic_failover_main_back_as_main():
mg_sleep_and_assert([("main",)], retrieve_data_show_repl_role_instance3)
def test_disable_multiple_mains():
safe_execute(shutil.rmtree, TEMP_DIR)
interactive_mg_runner.start_all(MEMGRAPH_INSTANCES_DESCRIPTION)
coord_cursor = connect(host="localhost", port=7690).cursor()
try:
execute_and_fetch_all(
coord_cursor,
"SET INSTANCE instance_1 TO MAIN;",
)
except Exception as e:
assert str(e) == "Couldn't set instance to main since there is already a main instance in cluster!"
if __name__ == "__main__":
sys.exit(pytest.main([__file__, "-rA"]))