diff --git a/docs/dev/topology-over-raft.md b/docs/dev/topology-over-raft.md index 7d2b304dec..79ec3cedef 100644 --- a/docs/dev/topology-over-raft.md +++ b/docs/dev/topology-over-raft.md @@ -369,7 +369,7 @@ emits a decision to finalize the split request. The finalization is serialized w doubling tablet count would interfere with the migration process. When the state machine leaves the migration track, and there are tablets waiting for tablet split to -be finalized, the topology will transition into `tablet_split_finalization` state. At this moment, there will +be finalized, the topology will transition into `tablet_resize_finalization` state. At this moment, there will be no migration running in the system. A global token metadata barrier is executed to make sure that no process e.g. repair will be holding stale metadata when finalizing split. After that, the new tablet map, which is a result of splitting each preexisting tablet into two, is committed to group0. diff --git a/service/storage_service.cc b/service/storage_service.cc index d3ce753ae6..93b5baf4ae 100644 --- a/service/storage_service.cc +++ b/service/storage_service.cc @@ -756,7 +756,7 @@ future<> storage_service::topology_state_load(state_change_hint hint) { [[fallthrough]]; case topology::transition_state::tablet_migration: [[fallthrough]]; - case topology::transition_state::tablet_split_finalization: + case topology::transition_state::tablet_resize_finalization: [[fallthrough]]; case topology::transition_state::commit_cdc_generation: [[fallthrough]]; diff --git a/service/tablet_allocator.cc b/service/tablet_allocator.cc index 988ba4fb7d..b93f236c21 100644 --- a/service/tablet_allocator.cc +++ b/service/tablet_allocator.cc @@ -2538,7 +2538,7 @@ public: load_balancer_stats_manager& stats() { return _load_balancer_stats; } - +private: // The splitting of tablets today is completely based on the power-of-two constraint. // A tablet of id X is split into 2 new tablets, which new ids are (x << 1) and // (x << 1) + 1. @@ -2565,6 +2565,14 @@ public: table, tablets.tablet_count(), new_tablets.tablet_count()); co_return std::move(new_tablets); } +public: + future resize_tablets(token_metadata_ptr tm, table_id table) { + auto& tmap = tm->tablets().get_tablet_map(table); + if (tmap.needs_split()) { + return split_tablets(std::move(tm), table); + } + throw std::logic_error(format("Table {} cannot be resized", table)); + } // FIXME: Handle materialized views. }; @@ -2598,8 +2606,8 @@ void tablet_allocator::set_use_table_aware_balancing(bool use_tablet_aware_balan impl().set_use_tablet_aware_balancing(use_tablet_aware_balancing); } -future tablet_allocator::split_tablets(locator::token_metadata_ptr tm, table_id table) { - return impl().split_tablets(std::move(tm), table); +future tablet_allocator::resize_tablets(locator::token_metadata_ptr tm, table_id table) { + return impl().resize_tablets(std::move(tm), table); } tablet_allocator_impl& tablet_allocator::impl() { diff --git a/service/tablet_allocator.hh b/service/tablet_allocator.hh index a7a862f6d2..9305607074 100644 --- a/service/tablet_allocator.hh +++ b/service/tablet_allocator.hh @@ -234,7 +234,7 @@ public: void set_use_table_aware_balancing(bool); - future split_tablets(locator::token_metadata_ptr, table_id); + future resize_tablets(locator::token_metadata_ptr, table_id); /// Should be called when the node is no longer a leader. void on_leadership_lost(); diff --git a/service/topology_coordinator.cc b/service/topology_coordinator.cc index 1112b50947..9856f14484 100644 --- a/service/topology_coordinator.cc +++ b/service/topology_coordinator.cc @@ -1464,7 +1464,7 @@ class topology_coordinator : public endpoint_lifecycle_subscriber { co_await update_topology_state(std::move(guard), std::move(updates), "Finished tablet migration"); } - future<> handle_tablet_split_finalization(group0_guard g) { + future<> handle_tablet_resize_finalization(group0_guard g) { // Executes a global barrier to guarantee that any process (e.g. repair) holding stale version // of token metadata will complete before we update topology. auto guard = co_await global_tablet_token_metadata_barrier(std::move(g)); @@ -1477,7 +1477,7 @@ class topology_coordinator : public endpoint_lifecycle_subscriber { for (auto& table_id : plan.resize_plan().finalize_resize) { auto s = _db.find_schema(table_id); - auto new_tablet_map = co_await _tablet_allocator.split_tablets(tm, table_id); + auto new_tablet_map = co_await _tablet_allocator.resize_tablets(tm, table_id); updates.emplace_back(co_await replica::tablet_map_to_mutation( new_tablet_map, table_id, @@ -2095,8 +2095,8 @@ class topology_coordinator : public endpoint_lifecycle_subscriber { case topology::transition_state::tablet_migration: co_await handle_tablet_migration(std::move(guard), false); break; - case topology::transition_state::tablet_split_finalization: - co_await handle_tablet_split_finalization(std::move(guard)); + case topology::transition_state::tablet_resize_finalization: + co_await handle_tablet_resize_finalization(std::move(guard)); break; case topology::transition_state::left_token_ring: { auto node = get_node_to_work_on(std::move(guard)); @@ -2544,8 +2544,8 @@ class topology_coordinator : public endpoint_lifecycle_subscriber { // Returns true if the state machine was transitioned into tablet migration path. future maybe_start_tablet_migration(group0_guard); - // Returns true if the state machine was transitioned into tablet split finalization path. - future maybe_start_tablet_split_finalization(group0_guard, const table_resize_plan& plan); + // Returns true if the state machine was transitioned into tablet resize finalization path. + future maybe_start_tablet_resize_finalization(group0_guard, const table_resize_plan& plan); future refresh_tablet_load_stats(); future<> start_tablet_load_stats_refresher(); @@ -2638,10 +2638,10 @@ future topology_coordinator::maybe_start_tablet_migration(group0_guard gua co_await generate_migration_updates(updates, guard, plan); - // We only want to consider transitioning into tablet split finalization path, if there's no other work + // We only want to consider transitioning into tablet resize finalization path, if there's no other work // to be done (e.g. start migration or/and emit split decision). if (updates.empty()) { - co_return co_await maybe_start_tablet_split_finalization(std::move(guard), plan.resize_plan()); + co_return co_await maybe_start_tablet_resize_finalization(std::move(guard), plan.resize_plan()); } updates.emplace_back( @@ -2654,7 +2654,7 @@ future topology_coordinator::maybe_start_tablet_migration(group0_guard gua co_return true; } -future topology_coordinator::maybe_start_tablet_split_finalization(group0_guard guard, const table_resize_plan& plan) { +future topology_coordinator::maybe_start_tablet_resize_finalization(group0_guard guard, const table_resize_plan& plan) { if (plan.finalize_resize.empty()) { co_return false; } @@ -2666,11 +2666,11 @@ future topology_coordinator::maybe_start_tablet_split_finalization(group0_ updates.emplace_back( topology_mutation_builder(guard.write_timestamp()) - .set_transition_state(topology::transition_state::tablet_split_finalization) + .set_transition_state(topology::transition_state::tablet_resize_finalization) .set_version(_topo_sm._topology.version + 1) .build()); - co_await update_topology_state(std::move(guard), std::move(updates), "Started tablet split finalization"); + co_await update_topology_state(std::move(guard), std::move(updates), "Started tablet resize finalization"); co_return true; } diff --git a/service/topology_state_machine.cc b/service/topology_state_machine.cc index be783b52b8..045e57fe47 100644 --- a/service/topology_state_machine.cc +++ b/service/topology_state_machine.cc @@ -147,18 +147,27 @@ static std::unordered_map transition_state_ {topology::transition_state::write_both_read_old, "write both read old"}, {topology::transition_state::write_both_read_new, "write both read new"}, {topology::transition_state::tablet_migration, "tablet migration"}, - {topology::transition_state::tablet_split_finalization, "tablet split finalization"}, + {topology::transition_state::tablet_resize_finalization, "tablet resize finalization"}, {topology::transition_state::tablet_draining, "tablet draining"}, {topology::transition_state::left_token_ring, "left token ring"}, {topology::transition_state::rollback_to_normal, "rollback to normal"}, }; +// Allows old deprecated names to be recognized and point to the correct transition. +static std::unordered_map deprecated_name_to_transition_state = { + {"tablet split finalization", topology::transition_state::tablet_resize_finalization}, +}; + topology::transition_state transition_state_from_string(const sstring& s) { for (auto&& e : transition_state_to_name_map) { if (e.second == s) { return e.first; } } + auto it = deprecated_name_to_transition_state.find(s); + if (it != deprecated_name_to_transition_state.end()) { + return it->second; + } on_internal_error(tsmlogger, format("cannot map name {} to transition_state", s)); } diff --git a/service/topology_state_machine.hh b/service/topology_state_machine.hh index 0c0119de1f..f62b2055bd 100644 --- a/service/topology_state_machine.hh +++ b/service/topology_state_machine.hh @@ -110,7 +110,7 @@ struct topology { write_both_read_old, write_both_read_new, tablet_migration, - tablet_split_finalization, + tablet_resize_finalization, left_token_ring, rollback_to_normal, }; diff --git a/test/boost/tablets_test.cc b/test/boost/tablets_test.cc index c8533ae451..fe87ef2638 100644 --- a/test/boost/tablets_test.cc +++ b/test/boost/tablets_test.cc @@ -33,6 +33,7 @@ #include "utils/error_injection.hh" #include "utils/to_string.hh" #include "service/topology_coordinator.hh" +#include "service/topology_state_machine.hh" #include @@ -3316,3 +3317,10 @@ SEASTAR_TEST_CASE(test_explicit_tablets_disable) { co_await test_create_keyspace("test_explictly_enabled_0", true, cfg, 0); co_await test_create_keyspace("test_explictly_enabled_128", true, cfg, 128); } + +SEASTAR_TEST_CASE(test_recognition_of_deprecated_name_for_resize_transition) { + using transition_state = service::topology::transition_state; + BOOST_REQUIRE_EQUAL(service::transition_state_from_string("tablet split finalization"), transition_state::tablet_resize_finalization); + BOOST_REQUIRE_EQUAL(service::transition_state_from_string("tablet resize finalization"), transition_state::tablet_resize_finalization); + return make_ready_future<>(); +}