Skip to content

Commit 5ce141c

Browse files
Merge pull request #2255 from rabbitmq/qq-remove-member-fix
Split QQ remove member into two operations
2 parents 1cc662c + 5e99e87 commit 5ce141c

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

src/rabbit_quorum_queue.erl

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
filter_quorum_critical/1, filter_quorum_critical/2,
4747
all_replica_states/0]).
4848
-export([is_policy_applicable/2]).
49+
-export([repair_amqqueue_nodes/1,
50+
repair_amqqueue_nodes/2
51+
]).
4952

5053
-include_lib("stdlib/include/qlc.hrl").
5154
-include("rabbit.hrl").
@@ -376,7 +379,38 @@ repair_leader_record(QName, Self) ->
376379
end,
377380
ok.
378381

379-
382+
repair_amqqueue_nodes(VHost, QueueName) ->
383+
QName = #resource{virtual_host = VHost, name = QueueName, kind = queue},
384+
repair_amqqueue_nodes(QName).
385+
386+
-spec repair_amqqueue_nodes(rabbit_types:r('queue') | amqqueue:amqqueue()) ->
387+
ok | repaired.
388+
repair_amqqueue_nodes(QName = #resource{}) ->
389+
{ok, Q0} = rabbit_amqqueue:lookup(QName),
390+
repair_amqqueue_nodes(Q0);
391+
repair_amqqueue_nodes(Q0) ->
392+
QName = amqqueue:get_name(Q0),
393+
Leader = amqqueue:get_pid(Q0),
394+
{ok, Members, _} = ra:members(Leader),
395+
RaNodes = [N || {_, N} <- Members],
396+
#{nodes := Nodes} = amqqueue:get_type_state(Q0),
397+
case lists:sort(RaNodes) =:= lists:sort(Nodes) of
398+
true ->
399+
%% up to date
400+
ok;
401+
false ->
402+
%% update amqqueue record
403+
Fun = fun (Q) ->
404+
TS0 = amqqueue:get_type_state(Q),
405+
TS = TS0#{nodes => RaNodes},
406+
amqqueue:set_type_state(Q, TS)
407+
end,
408+
rabbit_misc:execute_mnesia_transaction(
409+
fun() ->
410+
rabbit_amqqueue:update(QName, Fun)
411+
end),
412+
repaired
413+
end.
380414

381415
reductions(Name) ->
382416
try
@@ -899,8 +933,8 @@ delete_member(Q, Node) when ?amqqueue_is_quorum(Q) ->
899933
%% deleting the last member is not allowed
900934
{error, last_node};
901935
Members ->
902-
case ra:leave_and_delete_server(Members, ServerId) of
903-
ok ->
936+
case ra:remove_member(Members, ServerId) of
937+
{ok, _, _Leader} ->
904938
Fun = fun(Q1) ->
905939
update_type_state(
906940
Q1,
@@ -910,8 +944,15 @@ delete_member(Q, Node) when ?amqqueue_is_quorum(Q) ->
910944
end,
911945
rabbit_misc:execute_mnesia_transaction(
912946
fun() -> rabbit_amqqueue:update(QName, Fun) end),
913-
ok;
914-
timeout ->
947+
case ra:force_delete_server(ServerId) of
948+
ok ->
949+
ok;
950+
{error, _} = Err ->
951+
Err;
952+
Err ->
953+
{error, Err}
954+
end;
955+
{timeout, _} ->
915956
{error, timeout};
916957
E ->
917958
E

test/quorum_queue_SUITE.erl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ groups() ->
7070
recover_from_multiple_failures,
7171
leadership_takeover,
7272
delete_declare,
73+
delete_member_during_node_down,
7374
metrics_cleanup_on_leadership_takeover,
7475
metrics_cleanup_on_leader_crash,
7576
consume_in_minority,
@@ -1413,6 +1414,24 @@ delete_member_not_a_member(Config) ->
14131414
rpc:call(Server, rabbit_quorum_queue, delete_member,
14141415
[<<"/">>, QQ, Server])).
14151416

1417+
delete_member_during_node_down(Config) ->
1418+
[Server, DownServer, _] = rabbit_ct_broker_helpers:get_node_configs(
1419+
Config, nodename),
1420+
1421+
stop_node(Config, DownServer),
1422+
Ch = rabbit_ct_client_helpers:open_channel(Config, Server),
1423+
QQ = ?config(queue_name, Config),
1424+
?assertEqual({'queue.declare_ok', QQ, 0, 0},
1425+
declare(Ch, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])),
1426+
timer:sleep(200),
1427+
?assertEqual(ok, rpc:call(Server, rabbit_quorum_queue, delete_member,
1428+
[<<"/">>, QQ, Server])),
1429+
1430+
rabbit_ct_broker_helpers:start_node(Config, DownServer),
1431+
?assertEqual(ok, rpc:call(Server, rabbit_quorum_queue, repair_amqqueue_nodes,
1432+
[<<"/">>, QQ])),
1433+
ok.
1434+
14161435
%% These tests check if node removal would cause any queues to lose (or not lose)
14171436
%% their quorum. See rabbitmq/rabbitmq-cli#389 for background.
14181437

0 commit comments

Comments
 (0)