From 828595786ab84863b247122bf16dec6f34d47a9a Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Wed, 3 Apr 2024 19:21:20 +0300 Subject: [PATCH 1/2] schema_tables: calculate_schema_digest: prevent stalls due to large mutations vector With a large number of table the schema mutations vector might get big enoug to cause reactor stalls when freed. For example, the following stall was hit on 2023.1.0~rc1-20230208.fe3cc281ec73 with 5000 tables: ``` (inlined by) ~vector at /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/bits/stl_vector.h:730 (inlined by) db::schema_tables::calculate_schema_digest(seastar::sharded&, enum_set >, seastar::noncopyable_function >)>) at ./db/schema_tables.cc:799 ``` This change returns a mutations generator from the `map` lambda coroutine so we can process them one at a time, destroy the mutations one at a time, and by that, reducing memory footprint and preventing reactor stalls. Fixes #18173 Signed-off-by: Benny Halevy (cherry picked from commit 95a5fba0ead421d08cf2611da448d080d699cf90) --- db/schema_tables.cc | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/db/schema_tables.cc b/db/schema_tables.cc index c132df913e..f27ffdc822 100644 --- a/db/schema_tables.cc +++ b/db/schema_tables.cc @@ -779,40 +779,35 @@ redact_columns_for_missing_features(mutation&& m, schema_features features) { */ future calculate_schema_digest(distributed& proxy, schema_features features, noncopyable_function accept_keyspace) { - auto map = [&proxy, features, accept_keyspace = std::move(accept_keyspace)] (sstring table) mutable -> future> { + using mutations_generator = coroutine::experimental::generator; + + auto map = [&proxy, features, accept_keyspace = std::move(accept_keyspace)] (sstring table) mutable -> mutations_generator { auto& db = proxy.local().get_db(); auto rs = co_await db::system_keyspace::query_mutations(db, NAME, table); auto s = db.local().find_schema(NAME, table); - std::vector mutations; for (auto&& p : rs->partitions()) { auto mut = co_await unfreeze_gently(p.mut(), s); auto partition_key = value_cast(utf8_type->deserialize(mut.key().get_component(*s, 0))); if (!accept_keyspace(partition_key)) { continue; } - mut = redact_columns_for_missing_features(std::move(mut), features); - mutations.emplace_back(std::move(mut)); - } - co_return mutations; - }; - auto reduce = [features] (auto& hash, auto&& mutations) { - for (const mutation& m : mutations) { - feed_hash_for_schema_digest(hash, m, features); + co_yield redact_columns_for_missing_features(std::move(mut), features); } }; auto hash = md5_hasher(); auto tables = all_table_names(features); { for (auto& table: tables) { - auto mutations = co_await map(table); - if (diff_logger.is_enabled(logging::log_level::trace)) { - for (const mutation& m : mutations) { + auto gen_mutations = map(table); + while (auto mut_opt = co_await gen_mutations()) { + auto& m = *mut_opt; + feed_hash_for_schema_digest(hash, m, features); + if (diff_logger.is_enabled(logging::log_level::trace)) { md5_hasher h; feed_hash_for_schema_digest(h, m, features); diff_logger.trace("Digest {} for {}, compacted={}", h.finalize(), m, compact_for_schema_digest(m)); } } - reduce(hash, mutations); } co_return utils::UUID_gen::get_name_UUID(hash.finalize()); } From 31f3ff37f49a1c2ca2e53d92e4b859f651f058f4 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Wed, 29 May 2024 10:27:56 +0300 Subject: [PATCH 2/2] schema_tables: calculate_schema_digest: filter the key earlier Currently, each frozen mutation we get from system_keyspace::query_mutations is unfrozen in whole to a mutation and only then we check its key with the provided `accept_keyspace` function. This is wasteful, since they key can be processed directly form the frozen mutation, before taking the toll of unfreezing it. Signed-off-by: Benny Halevy (cherry picked from commit 52234214e54f3fd6e3c62625c68dc72fd98de722) --- db/schema_tables.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/schema_tables.cc b/db/schema_tables.cc index f27ffdc822..030aabf6ac 100644 --- a/db/schema_tables.cc +++ b/db/schema_tables.cc @@ -786,11 +786,11 @@ future calculate_schema_digest(distributedpartitions()) { - auto mut = co_await unfreeze_gently(p.mut(), s); - auto partition_key = value_cast(utf8_type->deserialize(mut.key().get_component(*s, 0))); + auto partition_key = value_cast(utf8_type->deserialize(::partition_key(p.mut().key()).get_component(*s, 0))); if (!accept_keyspace(partition_key)) { continue; } + auto mut = co_await unfreeze_gently(p.mut(), s); co_yield redact_columns_for_missing_features(std::move(mut), features); } };