Skip to content

Commit 2f7474d

Browse files
committed
rabbit_db_cluster: Move forget_node() generic steps from rabbit_mnesia
[Why] `rabbit_mnesia` indirectly checks that `rabbit` is stopped on the remote node because `mnesia:del_table_copy()` requires that Mnesia is stopped to delete the schema. However, this is not specific to Mnesia and we want `rabbit` to be stopped when we use Khepri in the future. Then, after a successful `forget_node()`, `rabbit_mnesia` would remove some queues and emit an event. Again, this is not specific to Mnesia and we want that to be handled by `rabbit_db_cluster`. [How] We use `rabbit:is_running(Node)` to query the status of RabbitMQ on the remote node to forget. This is not atomic so there is a small chance that RabbitMQ is restarted between the check and the actual forget. The rest was simply moved from `rabbit_mnesia` to `rabbit_db_cluster`.
1 parent 3184821 commit 2f7474d

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

deps/rabbit/src/rabbit_db_cluster.erl

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,27 @@ join_using_mnesia(ClusterNodes, NodeType) when is_list(ClusterNodes) ->
109109
%% @doc Removes `Node' from the cluster.
110110

111111
forget_member(Node, RemoveWhenOffline) ->
112-
rabbit_db:run(
113-
#{mnesia =>
114-
fun() -> forget_member_using_mnesia(Node, RemoveWhenOffline) end}).
112+
IsRunning = rabbit:is_running(Node),
113+
case rabbit:is_running(Node) of
114+
false ->
115+
Ret = rabbit_db:run(
116+
#{mnesia => fun() ->
117+
forget_member_using_mnesia(
118+
Node, RemoveWhenOffline)
119+
end
120+
}),
121+
case Ret of
122+
ok when IsRunning andalso not RemoveWhenOffline ->
123+
rabbit_amqqueue:forget_all_durable(Node),
124+
rabbit_node_monitor:notify_left_cluster(Node),
125+
ok;
126+
_ ->
127+
ok
128+
end,
129+
Ret;
130+
true ->
131+
{error, {failed_to_remove_node, Node, rabbit_still_running}}
132+
end.
115133

116134
forget_member_using_mnesia(Node, RemoveWhenOffline) ->
117135
rabbit_mnesia:forget_cluster_node(Node, RemoveWhenOffline).

deps/rabbit/src/rabbit_mnesia.erl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,6 @@ remove_node_if_mnesia_running(Node) ->
891891
%% change being propagated to all nodes
892892
case mnesia:del_table_copy(schema, Node) of
893893
{atomic, ok} ->
894-
rabbit_amqqueue:forget_all_durable(Node),
895-
rabbit_node_monitor:notify_left_cluster(Node),
896894
ok;
897895
{aborted, Reason} ->
898896
{error, {failed_to_remove_node, Node, Reason}}

deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/forget_cluster_node_command.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForgetClusterNodeCommand do
5858
end
5959

6060
case ret do
61+
{:error, {:failed_to_remove_node, ^atom_name, :rabbit_still_running}} ->
62+
{:error,
63+
"RabbitMQ on node #{node_to_remove} must be stopped with 'rabbitmqctl -n #{node_to_remove} stop_app' before it can be removed"}
64+
6165
{:error, {:failed_to_remove_node, ^atom_name, {:active, _, _}}} ->
6266
{:error,
6367
"RabbitMQ on node #{node_to_remove} must be stopped with 'rabbitmqctl -n #{node_to_remove} stop_app' before it can be removed"}

0 commit comments

Comments
 (0)