diff options
author | Matthias Radestock <matthias@rabbitmq.com> | 2012-09-15 12:27:20 +0100 |
---|---|---|
committer | Matthias Radestock <matthias@rabbitmq.com> | 2012-09-15 12:27:20 +0100 |
commit | 7cf07f3020439490d4ef62536a27a58f8fa1fc7f (patch) | |
tree | e0808a17e3b941c01acb7ebc69b572535bb51a38 | |
parent | 36bb3df65be376e9236b7907a9951d9a36e681b5 (diff) | |
download | rabbitmq-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.erl | 7 | ||||
-rw-r--r-- | src/rabbit_binding.erl | 14 | ||||
-rw-r--r-- | src/rabbit_exchange.erl | 7 |
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), |