From 9237801d22a38d2643ffe94ab626c4d2815012dd Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Thu, 10 Oct 2013 10:55:46 +0200 Subject: mnesia: Synchronize lock cleanup after mnesia down Bad timing could lead to hanging transactions after a mnesia down from a node with sticky locks. Excellent bug report from janchochol Situation: * node A and B have copies of table T * node A ows sticky of table T * node A goes down (e.g. crash) * node B tries to perform transactional operation on table T (e.g. mnesia:select) In this situation there is possibility that first (and maybe other) transaction on node B will hang indefinitely. This is caused by race condition, when transaction process send lock request operation to node A and waits for reply. When node A is down it will never send reply, so process on node B will be stuck forever. Reason is that message sent to mnesia_locker gen_server from mnesia_locker:mnesia_down can be received after mnesia_locker gen_server already replies to transaction processes with {switch, N, Req} and node N is down. Monitoring remote process when sending request to other node should be safe solution. --- lib/mnesia/src/mnesia_monitor.erl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'lib/mnesia/src/mnesia_monitor.erl') diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl index 7a788238fc..438da65158 100644 --- a/lib/mnesia/src/mnesia_monitor.erl +++ b/lib/mnesia/src/mnesia_monitor.erl @@ -482,11 +482,7 @@ handle_cast({mnesia_down, mnesia_controller, Node}, State) -> mnesia_tm:mnesia_down(Node), {noreply, State}; -handle_cast({mnesia_down, mnesia_tm, {Node, Pending}}, State) -> - mnesia_locker:mnesia_down(Node, Pending), - {noreply, State}; - -handle_cast({mnesia_down, mnesia_locker, Node}, State) -> +handle_cast({mnesia_down, mnesia_tm, Node}, State) -> Down = {mnesia_down, Node}, mnesia_lib:report_system_event(Down), GoingDown = lists:delete(Node, State#state.going_down), -- cgit v1.2.3