diff options
| author | Michael Klishin <michael@novemberain.com> | 2018-10-03 02:24:36 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-10-03 02:24:36 +0300 |
| commit | da4a6c0d31f8abd812b7f47384f32c816d31ceb1 (patch) | |
| tree | 0a7ea7c79ed0ee775d716dec6187cdc363ab945f | |
| parent | c1fb658ce13ae7f14919bd784eddd3dc77ab5144 (diff) | |
| parent | a9dc1f82e4e19519685c869cbb0772b2614f4d98 (diff) | |
| download | rabbitmq-server-git-da4a6c0d31f8abd812b7f47384f32c816d31ceb1.tar.gz | |
Merge pull request #1715 from rabbitmq/bindings-optimisation
Bindings optimisation
| -rw-r--r-- | src/rabbit_binding.erl | 44 | ||||
| -rw-r--r-- | src/rabbit_exchange.erl | 12 |
2 files changed, 37 insertions, 19 deletions
diff --git a/src/rabbit_binding.erl b/src/rabbit_binding.erl index f2bcd93b74..e96dfd7673 100644 --- a/src/rabbit_binding.erl +++ b/src/rabbit_binding.erl @@ -145,7 +145,7 @@ recover_semi_durable_route(Gatherer, R = #route{binding = B}, ToRecover) -> recover_semi_durable_route_txn(R = #route{binding = B}, X) -> rabbit_misc:execute_mnesia_transaction( fun () -> - case mnesia:match_object(rabbit_semi_durable_route, R, read) of + case mnesia:read(rabbit_semi_durable_route, B, read) of [] -> no_recover; _ -> ok = sync_transient_route(R, fun mnesia:write/3), rabbit_exchange:serial(X) @@ -232,7 +232,7 @@ remove(Src, Dst, B, ActingUser) -> lock_resource(Src), lock_resource(Dst), ok = sync_route(#route{binding = B}, durable(Src), durable(Dst), - fun mnesia:delete_object/3), + fun delete/3), Deletions = maybe_auto_delete( B#binding.source, [B], new_deletions(), false), process_deletions(Deletions, ActingUser). @@ -319,8 +319,8 @@ remove_for_source(SrcName) -> Match = #route{binding = #binding{source = SrcName, _ = '_'}}, remove_routes( lists:usort( - mnesia:match_object(rabbit_route, Match, read) ++ - mnesia:match_object(rabbit_semi_durable_route, Match, read))). + mnesia:dirty_match_object(rabbit_route, Match) ++ + mnesia:dirty_match_object(rabbit_semi_durable_route, Match))). remove_for_destination(DstName, OnlyDurable) -> remove_for_destination(DstName, OnlyDurable, fun remove_routes/1). @@ -406,21 +406,33 @@ remove_routes(Routes) -> %% This partitioning allows us to suppress unnecessary delete %% operations on disk tables, which require an fsync. {RamRoutes, DiskRoutes} = - lists:partition(fun (R) -> mnesia:match_object( - rabbit_durable_route, R, read) == [] end, + lists:partition(fun (R) -> mnesia:read( + rabbit_durable_route, R#route.binding, read) == [] end, Routes), + {RamOnlyRoutes, SemiDurableRoutes} = + lists:partition(fun (R) -> mnesia:read( + rabbit_semi_durable_route, R#route.binding, read) == [] end, + RamRoutes), %% Of course the destination might not really be durable but it's %% just as easy to try to delete it from the semi-durable table %% than check first - [ok = sync_route(R, false, true, fun mnesia:delete_object/3) || - R <- RamRoutes], - [ok = sync_route(R, true, true, fun mnesia:delete_object/3) || + [ok = sync_route(R, true, true, fun delete/3) || R <- DiskRoutes], + [ok = sync_route(R, false, true, fun delete/3) || + R <- SemiDurableRoutes], + [ok = sync_route(R, false, false, fun delete/3) || + R <- RamOnlyRoutes], [R#route.binding || R <- Routes]. + +delete(Tab, #route{binding = B}, LockKind) -> + mnesia:delete(Tab, B, LockKind); +delete(Tab, #reverse_route{reverse_binding = B}, LockKind) -> + mnesia:delete(Tab, B, LockKind). + remove_transient_routes(Routes) -> [begin - ok = sync_transient_route(R, fun mnesia:delete_object/3), + ok = sync_transient_route(R, fun delete/3), R#route.binding end || R <- Routes]. @@ -431,13 +443,13 @@ remove_for_destination(DstName, OnlyDurable, Fun) -> Routes = case OnlyDurable of false -> [reverse_route(R) || - R <- mnesia:match_object( - rabbit_reverse_route, MatchRev, read)]; + R <- mnesia:dirty_match_object( + rabbit_reverse_route, MatchRev)]; true -> lists:usort( - mnesia:match_object( - rabbit_durable_route, MatchFwd, read) ++ - mnesia:match_object( - rabbit_semi_durable_route, MatchFwd, read)) + mnesia:dirty_match_object( + rabbit_durable_route, MatchFwd) ++ + mnesia:dirty_match_object( + rabbit_semi_durable_route, MatchFwd)) end, Bindings = Fun(Routes), group_bindings_fold(fun maybe_auto_delete/4, new_deletions(), diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl index c7a849ce2e..92e3f9acbd 100644 --- a/src/rabbit_exchange.erl +++ b/src/rabbit_exchange.erl @@ -492,15 +492,21 @@ maybe_auto_delete(#exchange{auto_delete = true} = X, OnlyDurable) -> conditional_delete(X = #exchange{name = XName}, OnlyDurable) -> case rabbit_binding:has_for_source(XName) of - false -> unconditional_delete(X, OnlyDurable); + false -> internal_delete(X, OnlyDurable, false); true -> {error, in_use} end. -unconditional_delete(X = #exchange{name = XName}, OnlyDurable) -> +unconditional_delete(X, OnlyDurable) -> + internal_delete(X, OnlyDurable, true). + +internal_delete(X = #exchange{name = XName}, OnlyDurable, RemoveBindingsForSource) -> ok = mnesia:delete({rabbit_exchange, XName}), ok = mnesia:delete({rabbit_exchange_serial, XName}), mnesia:delete({rabbit_durable_exchange, XName}), - Bindings = rabbit_binding:remove_for_source(XName), + Bindings = case RemoveBindingsForSource of + true -> rabbit_binding:remove_for_source(XName); + false -> [] + end, {deleted, X, Bindings, rabbit_binding:remove_for_destination( XName, OnlyDurable)}. |
