New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add replace-node-first-boot option #12316
Add replace-node-first-boot option #12316
Conversation
async def test_replace_using_host_id_reuse_ip(manager: ManagerClient, random_tables) -> None: | ||
servers = await manager.running_servers() | ||
await manager.server_stop(servers[0].server_id) | ||
replace_cfg = ReplaceConfig(replaced_id = servers[0].server_id, reuse_ip_addr = True, use_host_id = True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could do the two replaces (using host ID and not using host ID) in a single test, so we don't grow the number of tests cases? Each test case requires starting a separate cluster - which takes some time.
(Maybe we should do the same with reuse_ip_addr
- but out of this PR's scope)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay.
Maybe we should take the same approach in
https://github.com/scylladb/scylla-dtest/pull/2946
@fruch what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kbr-scylla this has proven to be more difficult than I thought, since it the second replace in a row fails (ta least some of the times) because it sees one of the nodes as down. I think it's the first replacing node that is not recognized as UN by all other nodes when add_server resolves.
It's out of scope for this PR to deal with that, so I'll keep the tests separated and we can merge them as a follow up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Maybe I'll work on merging them later.
@@ -189,11 +189,11 @@ In this case, the node's data will be cleaned after restart. To remedy this, you | |||
|
|||
sudo sed -e '/auto_bootstrap:.*/s/False/True/g' -i /etc/scylla/scylla.yaml | |||
|
|||
#. Run the following command, replacing 172.30.0.186 with the listen_address / rpc_address of the node that you are restarting: | |||
#. Run the following command to replace the Host ID of the node that you are restarting: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous statement instructed the reader to take the command below, modify the command by replacing the IP provided here with the IP of the node that they want to restart, and then run the command.
This statement tells the reader that the command replaces the Host ID of the node that the reader is restarting... replaces it with what? This doesn't make much sense. And running the command verbatim is obviously an error - we don't want the reader to run the following command, actually (we want them to run a modified command).
I think we should keep the format of the statement as it was and write something like:
"Run the following command, replacing 87a2b646-c968-4108-a38b-f8468b8b7360 with the Host ID of the node that you are restarting"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually not happy with the phrase you suggested since the action is not about replacing the Host ID, it's about replacing the node previously known by that Host ID.
How about:
#. Run the following command to replace the node known by the previous Host ID of the node you are restarting, 87a2b646-c968-4108-a38b-f8468b8b7360, by the restarted instance, that will be assigned a new, random, Host ID:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
action is not about replacing the Host ID
The command itself is not about replacing the Host ID, but the reader of the documentation must first replace the Host ID in the command with the Host ID of their node. That's what the "replacing 87a2b646-c968-4108-a38b-f8468b8b7360 with..." is about.
So the statement is a succint wait of saying:
- In the command below, replace "87a2b646-c968-4108-a38b-f8468b8b7360" with the Host ID of the node that you are restarting
- Then execute the command below.
service/storage_service.hh
Outdated
const std::unordered_map<gms::inet_address, sstring>& loaded_peer_features); | ||
|
||
std::optional<replacement_info> _replacement_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't object to this, but I don't like putting more state inside the class :( It's not clear if this state is mutable, where it's needed etc. Would be nice if we could avoid it by just passing the replacement_info
where we need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree in principle, but unfortunately, the join_token_ring, handle_state_replacing song and dance requires this state :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not present in v5, instead
the local replacement_info prepared in join_token_ring is used to pass the replace address down to functions that need it and are called from join_token_ring
CI state |
I suggest adding a warning if the old replace options are used and point the user to use the new option instead. |
I added these warnings in prepare_replacement_info: } else if (!cfg.replace_address_first_boot().empty()) {
replace_address = gms::inet_address(cfg.replace_address_first_boot());
slogger.warn("The replace_address_first_boot={} option is deprecated. Please use the replace_node_first_boot option", replace_address);
} else if (!cfg.replace_address().empty()) {
replace_address = gms::inet_address(cfg.replace_address());
slogger.warn("The replace_address={} option is deprecated. Please use the replace_node_first_boot option", replace_address); |
06174c9
to
83e64db
Compare
In v2 (83e64db):
|
docs/operating-scylla/procedures/cluster-management/replace-dead-node.rst
Outdated
Show resolved
Hide resolved
docs/operating-scylla/procedures/cluster-management/replace-dead-node.rst
Outdated
Show resolved
Hide resolved
83e64db
to
ea57b93
Compare
In v3 (ea57b93):
|
CI state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs look good.
docs/operating-scylla/admin.rst
Outdated
* - replace_address_first_boot | ||
- Address of the node this Scylla instance is meant to replace. Refer to :doc:`Replace a Dead Node in a Scylla Cluster </operating-scylla/procedures/cluster-management/replace-dead-node>` for more details. | ||
* - replace_node_first_boot | ||
- Host ID of the node this Scylla instance is meant to replace. Refer to :doc:`Replace a Dead Node in a Scylla Cluster </operating-scylla/procedures/cluster-management/replace-dead-node>` for more details. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just in this sentence we use node, instance and host for the same thing. Could we settle on fewer names for the same thing perhaps or provide a glossary of what the differences are? At the very least we perhaps should consistently use "Scylla node" rather than "instance" in all places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. How about:
* - replace_node_first_boot
- Host ID of a dead node this Scylla node is replacing. Refer to ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rephrased in 6808aa1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still says "Host ID of the node this Scylla instance is meant to replace"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if I had a bad rebase that lost the above change that I mentioned...
Will (re-)fix
docs/operating-scylla/procedures/cluster-management/replace-dead-node.rst
Show resolved
Hide resolved
db/config.cc
Outdated
@@ -788,6 +788,7 @@ db::config::config(std::shared_ptr<db::extensions> exts) | |||
, consistent_rangemovement(this, "consistent_rangemovement", value_status::Used, true, "When set to true, range movements will be consistent. It means: 1) it will refuse to bootstrap a new node if other bootstrapping/leaving/moving nodes detected. 2) data will be streamed to a new node only from the node which is no longer responsible for the token range. Same as -Dcassandra.consistent.rangemovement in cassandra") | |||
, join_ring(this, "join_ring", value_status::Unused, true, "When set to true, a node will join the token ring. When set to false, a node will not join the token ring. User can use nodetool join to initiate ring joinging later. Same as -Dcassandra.join_ring in cassandra.") | |||
, load_ring_state(this, "load_ring_state", value_status::Used, true, "When set to true, load tokens and host_ids previously saved. Same as -Dcassandra.load_ring_state in cassandra.") | |||
, replace_node_first_boot(this, "replace_node_first_boot", value_status::Used, "", "The Host ID of the dead node to replace. If this node has been bootstrapped successfully, this option will be ignored.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is "this node"? Is "this node" the node to replace or the node that has been started with this option? Would be really nice to disambiguate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the replacing node. How about the following:
The Host ID of a dead node to replace. If the replacing node has already been bootstrapped successfully, this option will be ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rephrased in 6808aa1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still says "this node".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, will change.
Converted to draft until #12330 is merged. |
07d8629
to
6808aa1
Compare
6808aa1
to
dbfc33d
Compare
CI state |
dbfc33d
to
91e696f
Compare
In v6 (91e696f):
|
CI state |
cc @denesb Restarting the CI |
CI state |
Looks like #11842. |
Allow replacing a node given its Host ID rather than its ip address. This series adds a replace_node_first_boot option to db/config and makes use of it in storage_service. The new option takes priority over the legacy replace_address* options. When the latter are used, a deprecation warning is printed. Documentation updated respectively. And a cql unit_test is added. Ref #12277 Closes #12316 * github.com:scylladb/scylladb: docs: document the new replace_node_first_boot option dist/docker: support --replace-node-first-boot db: config: describe replace_address* options as deprecated test: test_topology: test replace using host_id test: pylib: ServerInfo: add host_id storage_service: get rid of get_replace_address storage_service: is_replacing: rely directly on config options storage_service: pass replace_address to run_replace_ops storage_service: pass replacement_info to booststrap storage_service: join_token_ring: reuse replacement_info.address storage_service: replacement_info: add replace address init: do not allow cfg.replace_node_first_boot of seed node db: config: add replace_node_first_boot option
@kbr-scylla this series got dequeued due to topology tests flakiness. |
Yes, the problem was too many test causing the test framework to run out of IPs, but that was fixed already. |
For replacing a node given its (now unique) Host ID. The existing options for replace_address* will be deprecated in the following patches and eventually we will stop supporting them. Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Populate replacement_info.address in prepare_replacement_info as a first step towards getting rid of get_replace_address(). Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
So it won't need to call get_replace_address. Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
So it won't need to call get_replace_address. Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Rather than on get_replace_address, before we remove the latter. Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
It is unused now. Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Add test cases exercising the --replace-node-first-boot option by replacing nodes using their host_id rather than ip address. Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
The replace_address options are still supported But mention in their description that they are now deprecated and the user should use replace_node_first_boot instead. While at it fix a typo in ignore_dead_nodes_for_replace Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
And mention that replace_address_first_boot is deprecated Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
And mention that replacing a node using the legacy replace_addr* options is deprecated. Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
91e696f
to
de3142e
Compare
v7 (de3142e):
|
CI state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Queued
Allow replacing a node given its Host ID rather than its ip address.
This series adds a replace_node_first_boot option to db/config
and makes use of it in storage_service.
The new option takes priority over the legacy replace_address* options.
When the latter are used, a deprecation warning is printed.
Documentation updated respectively.
And a cql unit_test is added.
Ref #12277