summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Radestock <matthias@rabbitmq.com>2012-09-15 12:27:20 +0100
committerMatthias Radestock <matthias@rabbitmq.com>2012-09-15 12:27:20 +0100
commit7cf07f3020439490d4ef62536a27a58f8fa1fc7f (patch)
treee0808a17e3b941c01acb7ebc69b572535bb51a38
parent36bb3df65be376e9236b7907a9951d9a36e681b5 (diff)
downloadrabbitmq-server-7cf07f3020439490d4ef62536a27a58f8fa1fc7f.tar.gz
guard deletes on disk tables in order to eliminate superfluos fsyncs
Unfortunately this makes queue deletion O(binding_count^2), so further work is needed.
-rw-r--r--src/rabbit_amqqueue.erl7
-rw-r--r--src/rabbit_binding.erl14
-rw-r--r--src/rabbit_exchange.erl7
3 files changed, 23 insertions, 5 deletions
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl
index d566ac87..b2473f91 100644
--- a/src/rabbit_amqqueue.erl
+++ b/src/rabbit_amqqueue.erl
@@ -578,7 +578,12 @@ flush_all(QPids, ChPid) ->
internal_delete1(QueueName) ->
ok = mnesia:delete({rabbit_queue, QueueName}),
- ok = mnesia:delete({rabbit_durable_queue, QueueName}),
+ %% this 'guarded' delete prevents unnecessary writes to the mnesia
+ %% disk log
+ case mnesia:wread({rabbit_durable_queue, QueueName}) of
+ [] -> ok;
+ [_] -> ok = mnesia:delete({rabbit_durable_queue, QueueName})
+ end,
%% we want to execute some things, as decided by rabbit_exchange,
%% after the transaction.
rabbit_binding:remove_for_destination(QueueName).
diff --git a/src/rabbit_binding.erl b/src/rabbit_binding.erl
index f0ea514d..540e221f 100644
--- a/src/rabbit_binding.erl
+++ b/src/rabbit_binding.erl
@@ -281,17 +281,17 @@ remove_for_source(SrcName) ->
mnesia:match_object(rabbit_route, Match, write) ++
mnesia:match_object(rabbit_durable_route, Match, write)),
[begin
- sync_route(Route, fun mnesia:delete_object/3),
+ sync_route(Route, fun delete_object/3),
Route#route.binding
end || Route <- Routes].
remove_for_destination(Dst) ->
remove_for_destination(
- Dst, fun (R) -> sync_route(R, fun mnesia:delete_object/3) end).
+ Dst, fun (R) -> sync_route(R, fun delete_object/3) end).
remove_transient_for_destination(Dst) ->
remove_for_destination(
- Dst, fun (R) -> sync_transient_route(R, fun mnesia:delete_object/3) end).
+ Dst, fun (R) -> sync_transient_route(R, fun delete_object/3) end).
%%----------------------------------------------------------------------------
@@ -308,6 +308,14 @@ binding_action(Binding = #binding{source = SrcName,
Fun(Src, Dst, Binding#binding{args = SortedArgs})
end).
+delete_object(Tab, Record, LockKind) ->
+ %% this 'guarded' delete prevents unnecessary writes to the mnesia
+ %% disk log
+ case mnesia:match_object(Tab, Record, LockKind) of
+ [] -> ok;
+ [_] -> mnesia:delete_object(Tab, Record, LockKind)
+ end.
+
sync_route(R, Fun) -> sync_route(R, true, true, Fun).
sync_route(Route, true, true, Fun) ->
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index 57c571f1..4cc96ef5 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -402,7 +402,12 @@ conditional_delete(X = #exchange{name = XName}) ->
end.
unconditional_delete(X = #exchange{name = XName}) ->
- ok = mnesia:delete({rabbit_durable_exchange, XName}),
+ %% this 'guarded' delete prevents unnecessary writes to the mnesia
+ %% disk log
+ case mnesia:wread({rabbit_durable_exchange, XName}) of
+ [] -> ok;
+ [_] -> ok = mnesia:delete({rabbit_durable_exchange, XName})
+ end,
ok = mnesia:delete({rabbit_exchange, XName}),
ok = mnesia:delete({rabbit_exchange_serial, XName}),
Bindings = rabbit_binding:remove_for_source(XName),