From 288e75fe22fdbe48267ed8d71cae51f9992467e4 Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Tue, 28 Oct 2025 18:17:48 +0100 Subject: [PATCH] tablets, topology_coordinator: Skip tablet draining on replace Replace doesn't drain (rebuild) tablets during topology change. They are rebuilt afterwards when the replaced node is in "left" state and replacing node is in normal state. So there is no point in attempting to drain, as nothing will be drained. Not only that, doing so has a risk, because the load balancer is invoked on a transitional topology state in which we can end up with no normal nodes in a rack. That's the case if the replaced node was the last one in the rack. This tripped one of the algorithms which computes rack's shard count for the purpose of determining ideal tablet count, it was not prepared to find an empty rack to which a table is still repliacated. That was fixed separately, but to avoid this, we better skip tablet draining here. --- service/topology_coordinator.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/service/topology_coordinator.cc b/service/topology_coordinator.cc index b2c490060f..82bb41437e 100644 --- a/service/topology_coordinator.cc +++ b/service/topology_coordinator.cc @@ -2325,12 +2325,14 @@ class topology_coordinator : public endpoint_lifecycle_subscriber { break; } - builder.set_transition_state(topology::transition_state::tablet_draining) + guard = take_guard(std::move(node)); + builder.set_transition_state(topology::transition_state::write_both_read_old) .set_version(_topo_sm._topology.version + 1) + .set_session(session_id(guard.new_group0_state_id())) .with_node(node.id) .set("tokens", it->second.ring->tokens); - co_await update_topology_state(take_guard(std::move(node)), {builder.build()}, - "replace: transition to tablet_draining and take ownership of the replaced node's tokens"); + co_await update_topology_state(std::move(guard), {builder.build()}, + "replace: transition to write_both_read_old and take ownership of the replaced node's tokens"); } break; default: