summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2013-02-18 16:47:40 +0000
committerSimon MacMullen <simon@rabbitmq.com>2013-02-18 16:47:40 +0000
commitec805b6b663515a9aad7d8f4b4f3deb30aab613f (patch)
tree38dd1830eb98349721ce4801cea0945962e1f00c /src
parent5e7d0a33022b12cb128356c35b0fd601e457bf17 (diff)
downloadrabbitmq-server-git-ec805b6b663515a9aad7d8f4b4f3deb30aab613f.tar.gz
cluster_cp_mode
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_mnesia.erl6
-rw-r--r--src/rabbit_node_monitor.erl26
2 files changed, 32 insertions, 0 deletions
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index c39e898cec..ecb03f54ba 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -26,6 +26,7 @@
status/0,
is_clustered/0,
+ majority/0,
cluster_nodes/1,
node_type/0,
dir/0,
@@ -67,6 +68,7 @@
-spec(status/0 :: () -> [{'nodes', [{node_type(), [node()]}]} |
{'running_nodes', [node()]} |
{'partitions', [{node(), [node()]}]}]).
+-spec(majority/0 :: () -> boolean()).
-spec(is_clustered/0 :: () -> boolean()).
-spec(cluster_nodes/1 :: ('all' | 'disc' | 'ram' | 'running') -> [node()]).
-spec(node_type/0 :: () -> node_type()).
@@ -338,6 +340,10 @@ status() ->
false -> []
end.
+majority() ->
+ ensure_mnesia_running(),
+ (length(cluster_nodes(running)) / length(cluster_nodes(all))) > 0.5.
+
mnesia_partitions(Nodes) ->
{Replies, _BadNodes} = rpc:multicall(
Nodes, rabbit_node_monitor, partitions, []),
diff --git a/src/rabbit_node_monitor.erl b/src/rabbit_node_monitor.erl
index 71c2c80ac7..7b7fed5ce6 100644
--- a/src/rabbit_node_monitor.erl
+++ b/src/rabbit_node_monitor.erl
@@ -250,6 +250,10 @@ handle_info({mnesia_system_event,
ordsets:add_element(Node, ordsets:from_list(Partitions))),
{noreply, State#state{partitions = Partitions1}};
+handle_info({mnesia_system_event, {mnesia_down, _Node}}, State) ->
+ handle_dead_according_to_mnesia_rabbit(),
+ {noreply, State};
+
handle_info(_Info, State) ->
{noreply, State}.
@@ -272,6 +276,28 @@ handle_dead_rabbit(Node) ->
ok = rabbit_alarm:on_node_down(Node),
ok = rabbit_mnesia:on_node_down(Node).
+%% Since we will be introspecting the cluster in response to this, we
+%% must only do so based on Mnesia having noticed the other node being
+%% down - otherwise we have a race.
+handle_dead_according_to_mnesia_rabbit() ->
+ case application:get_env(rabbit, cluster_cp_mode) of
+ {ok, true} -> case rabbit_mnesia:majority() of
+ true -> ok;
+ false -> stop_and_halt()
+ end;
+ {ok, false} -> ok
+ end,
+ ok.
+
+stop_and_halt() ->
+ rabbit_log:warning("Cluster minority status detected - stopping~n", []),
+ spawn(fun () ->
+ %% If our group leader is inside an application we are about
+ %% to stop, application:stop/1 does not return.
+ group_leader(whereis(init), self()),
+ rabbit:stop_and_halt()
+ end).
+
handle_live_rabbit(Node) ->
ok = rabbit_alarm:on_node_up(Node),
ok = rabbit_mnesia:on_node_up(Node).