From 590fa68fdc501b9bbca0ace56a3941461e62fce7 Mon Sep 17 00:00:00 2001 From: David Ansari Date: Fri, 27 Jan 2023 19:47:16 +0000 Subject: Fix direct_exchange_routing_v2 migration Multiple users reported the following error when starting RabbitMQ in containers: ``` Feature flags: failed to enable `direct_exchange_routing_v2`: {error, {badarg, [{ets,lookup, [rabbit_exchange, {resource, <<"/">>, exchange, <<"messages">>}], [{error_info, #{cause => id, module => erl_stdlib_errors}}]}, {rabbit_misc, dirty_read, 1, [{file, "rabbit_misc.erl"}, {line, 372}]}, {rabbit_binding, '-populate_index_route_table/0-fun-0-', 1, [{file, "rabbit_binding.erl"}, {line, 757}]}, ... ``` Although Mnesia table rabbit_exchange is present when the migration function for direct_exchange_routing_v2 runs, its ETS table is not yet present because there is no table copy on the local node. The table copy was added later after all feature flags were synced. Fixes #7068. --- deps/rabbit/src/rabbit_core_ff.erl | 13 ++++++++----- deps/rabbit/src/rabbit_table.erl | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/deps/rabbit/src/rabbit_core_ff.erl b/deps/rabbit/src/rabbit_core_ff.erl index 2be2bd23b3..825fb11c80 100644 --- a/deps/rabbit/src/rabbit_core_ff.erl +++ b/deps/rabbit/src/rabbit_core_ff.erl @@ -133,19 +133,22 @@ Args :: rabbit_feature_flags:enable_callback_args(), Ret :: rabbit_feature_flags:enable_callback_ret(). direct_exchange_routing_v2_enable(#{feature_name := FeatureName}) -> - TableName = rabbit_index_route, - ok = rabbit_table:wait([rabbit_route, rabbit_exchange], _Retry = true), + DependantTables = [rabbit_route, rabbit_exchange], + ok = rabbit_table:wait(DependantTables, _Retry = true), + [ok = rabbit_table:create_local_copy(Tab, ram_copies) || Tab <- DependantTables], + + NewTable = rabbit_index_route, try ok = rabbit_table:create( - TableName, rabbit_table:rabbit_index_route_definition()), - case rabbit_table:ensure_table_copy(TableName, node(), ram_copies) of + NewTable, rabbit_table:rabbit_index_route_definition()), + case rabbit_table:ensure_table_copy(NewTable, node(), ram_copies) of ok -> ok = rabbit_binding:populate_index_route_table(); {error, Err} = Error -> ?LOG_ERROR( "Feature flags: `~ts`: failed to add copy of table ~ts to " "node ~tp: ~tp", - [FeatureName, TableName, node(), Err], + [FeatureName, NewTable, node(), Err], #{domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}), Error end diff --git a/deps/rabbit/src/rabbit_table.erl b/deps/rabbit/src/rabbit_table.erl index b5d2307171..6418f68c1d 100644 --- a/deps/rabbit/src/rabbit_table.erl +++ b/deps/rabbit/src/rabbit_table.erl @@ -9,7 +9,7 @@ -export([ create/0, create/2, ensure_local_copies/1, ensure_table_copy/3, - wait_for_replicated/1, wait/1, wait/2, + create_local_copy/2, wait_for_replicated/1, wait/1, wait/2, force_load/0, is_present/0, is_empty/0, needs_default_data/0, check_schema_integrity/1, clear_ram_only_tables/0, retry_timeout/0, wait_for_replicated/0, exists/1]). @@ -74,7 +74,7 @@ ensure_secondary_index(Table, Field) -> {aborted, {already_exists, Table, _}} -> ok end. --spec ensure_table_copy(atom(), node(), ram_copies | disc_copies) -> +-spec ensure_table_copy(mnesia:table(), node(), mnesia:storage_type()) -> ok | {error, any()}. ensure_table_copy(TableName, Node, StorageType) -> rabbit_log:debug("Will add a local schema database copy for table '~ts'", [TableName]), @@ -239,6 +239,7 @@ create_local_copies(Type) -> end, definitions(Type)), ok. +-spec create_local_copy(mnesia:table(), mnesia:storage_type()) -> ok. create_local_copy(Tab, Type) -> StorageType = mnesia:table_info(Tab, storage_type), {atomic, ok} = -- cgit v1.2.1