Faster implementation of rabbit_binding:recover/0

For a large number of bindings, this implementation reduces the recovery
time from minutes to seconds. rabbit_binding:recover/2 is the second
operation that may take minutes but it can be improved separately.
This commit is contained in:
Michal Kuratczyk 2021-06-22 15:01:42 +02:00
parent 0cbef999cc
commit 46f6d81ad0
2 changed files with 19 additions and 11 deletions

View File

@ -77,15 +77,16 @@ new(Src, RoutingKey, Dst, Arguments) ->
%% Global table recovery
recover() ->
rabbit_misc:table_filter(
fun (Route) ->
mnesia:read({rabbit_semi_durable_route, Route}) =:= []
end,
fun (Route, true) ->
ok = mnesia:write(rabbit_semi_durable_route, Route, write);
(_Route, false) ->
ok
end, rabbit_durable_route).
rabbit_misc:execute_mnesia_transaction(
fun () ->
mnesia:lock({table, rabbit_durable_route}, read),
mnesia:lock({table, rabbit_semi_durable_route}, write),
Routes = rabbit_misc:dirty_read_all(rabbit_durable_route),
Fun = fun(Route) ->
mnesia:dirty_write(rabbit_semi_durable_route, Route)
end,
lists:foreach(Fun, Routes)
end).
%% Virtual host-specific recovery

View File

@ -37,7 +37,10 @@ recover() ->
rabbit_amqqueue:warn_file_limit(),
%% Prepare rabbit_semi_durable_route table
rabbit_binding:recover(),
{Time, _} = timer:tc(fun() ->
rabbit_binding:recover()
end),
rabbit_log:debug("rabbit_binding:recover/0 completed in ~fs", [Time/1000000]),
%% rabbit_vhost_sup_sup will start the actual recovery.
%% So recovery will be run every time a vhost supervisor is restarted.
@ -57,7 +60,11 @@ recover(VHost) ->
{Recovered, Failed} = rabbit_amqqueue:recover(VHost),
AllQs = Recovered ++ Failed,
QNames = [amqqueue:get_name(Q) || Q <- AllQs],
ok = rabbit_binding:recover(rabbit_exchange:recover(VHost), QNames),
{Time, ok} = timer:tc(fun() ->
rabbit_binding:recover(rabbit_exchange:recover(VHost), QNames)
end),
rabbit_log:debug("rabbit_binding:recover/2 for vhost ~s completed in ~fs", [VHost, Time/1000000]),
ok = rabbit_amqqueue:start(Recovered),
%% Start queue mirrors.
ok = rabbit_mirror_queue_misc:on_vhost_up(VHost),