From 67995db8999035ebd6d06b53db7564ef7ef16617 Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 26 Mar 2020 10:11:03 +0800 Subject: [PATCH] gossip: Add an option to force gossip generation Consider 3 nodes in the cluster, n1, n2, n3 with gossip generation number g1, g2, g3. n1, n2, n3 running scylla version with commit 0a52ecb6df3deec729759ea87b4986334f207c07 (gossip: Fix max generation drift measure) One year later, user wants the upgrade n1,n2,n3 to a new version when n3 does a rolling restart with a new version, n3 will use a generation number g3'. Because g3' - g2 > MAX_GENERATION_DIFFERENCE and g3' - g1 > MAX_GENERATION_DIFFERENCE, so g1 and g2 will reject n3's gossip update and mark g3 as down. Such unnecessary marking of node down can cause availability issues. For example: DC1: n1, n2 DC2: n3, n4 When n3 and n4 restart, n1 and n2 will mark n3 and n4 as down, which causes the whole DC2 to be unavailable. To fix, we can start the node with a gossip generation within MAX_GENERATION_DIFFERENCE difference for the new node. Once all the nodes run the version with commit 0a52ecb6df3deec729759ea87b4986334f207c07, the option is no logger needed. Fixes #5164 (cherry picked from commit 743b529c2b035658d33afd14f6a01beff3097b12) --- db/config.cc | 1 + db/config.hh | 1 + gms/gossiper.cc | 6 +++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/db/config.cc b/db/config.cc index 738a610c9f..17649dfe7d 100644 --- a/db/config.cc +++ b/db/config.cc @@ -689,6 +689,7 @@ db::config::config(std::shared_ptr exts) , shutdown_announce_in_ms(this, "shutdown_announce_in_ms", value_status::Used, 2 * 1000, "Time a node waits after sending gossip shutdown message in milliseconds. Same as -Dcassandra.shutdown_announce_in_ms in cassandra.") , developer_mode(this, "developer_mode", value_status::Used, false, "Relax environment checks. Setting to true can reduce performance and reliability significantly.") , skip_wait_for_gossip_to_settle(this, "skip_wait_for_gossip_to_settle", value_status::Used, -1, "An integer to configure the wait for gossip to settle. -1: wait normally, 0: do not wait at all, n: wait for at most n polls. Same as -Dcassandra.skip_wait_for_gossip_to_settle in cassandra.") + , force_gossip_generation(this, "force_gossip_generation", liveness::LiveUpdate, value_status::Used, -1 , "Force gossip to use the generation number provided by user") , experimental(this, "experimental", value_status::Used, false, "Set to true to unlock all experimental features.") , experimental_features(this, "experimental_features", value_status::Used, {}, "Unlock experimental features provided as the option arguments (possible values: 'lwt', 'cdc', 'udf'). Can be repeated.") , lsa_reclamation_step(this, "lsa_reclamation_step", value_status::Used, 1, "Minimum number of segments to reclaim in a single step") diff --git a/db/config.hh b/db/config.hh index f257838981..0be90c6d35 100644 --- a/db/config.hh +++ b/db/config.hh @@ -278,6 +278,7 @@ public: named_value shutdown_announce_in_ms; named_value developer_mode; named_value skip_wait_for_gossip_to_settle; + named_value force_gossip_generation; named_value experimental; named_value>> experimental_features; named_value lsa_reclamation_step; diff --git a/gms/gossiper.cc b/gms/gossiper.cc index 3efc9e8e4c..9ead549e05 100644 --- a/gms/gossiper.cc +++ b/gms/gossiper.cc @@ -1725,8 +1725,12 @@ future<> gossiper::start_gossiping(int generation_nbr, std::map 0) { + generation_nbr = _cfg.force_gossip_generation(); + logger.warn("Use the generation number provided by user: generation = {}", generation_nbr); + } endpoint_state& local_state = endpoint_state_map[get_broadcast_address()]; local_state.set_heart_beat_state_and_update_timestamp(heart_beat_state(generation_nbr)); local_state.mark_alive();