summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Scvortov <alexandru@rabbitmq.com>2011-07-20 15:28:01 +0100
committerAlexandru Scvortov <alexandru@rabbitmq.com>2011-07-20 15:28:01 +0100
commitc2bc79c3aa64213305e79d61895127d3d0fff507 (patch)
tree5ac9a5bb79c6c47b5ec4d452efb3c4ac52637167
parent54bc319414f0f04f7961abcbff8a72c40c063286 (diff)
downloadrabbitmq-server-c2bc79c3aa64213305e79d61895127d3d0fff507.tar.gz
reset before changing node type
Matthias points out that the only way for mnesia:change_config to start creating tables is for the node to re-join the cluster (and get its old table definitions from other nodes). Instead of fixing the tables after that, we now reset inside the cluster command. Note that in very old rabbit versions, we'd just prevent this by having the user reset manually.
-rw-r--r--src/rabbit_mnesia.erl57
-rw-r--r--src/rabbit_tests.erl4
2 files changed, 24 insertions, 37 deletions
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index 805b4152..6b901eae 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -117,6 +117,22 @@ force_cluster(ClusterNodes) ->
cluster(ClusterNodes, Force) ->
ensure_mnesia_not_running(),
ensure_mnesia_dir(),
+
+ %% Reset the node if we're in a cluster and have just changed node type
+ rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia),
+ AllClusteredNodes =
+ lists:usort(all_clustered_nodes() ++
+ read_cluster_nodes_config()) -- [node()],
+ mnesia:stop(),
+ case {AllClusteredNodes =/= [],
+ is_disc_node() =/= should_be_disc_node(ClusterNodes)} of
+ {true, true} -> error_logger:warning_msg("changing node type; "
+ "resetting...~n"),
+ reset();
+ {_, _} -> ok
+ end,
+
+ %% Join the cluster
rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia),
try
ok = init_db(ClusterNodes, Force,
@@ -431,7 +447,7 @@ delete_previously_running_nodes() ->
init_db(ClusterNodes, Force, SecondaryPostMnesiaFun) ->
UClusterNodes = lists:usort(ClusterNodes),
ProperClusterNodes = UClusterNodes -- [node()],
- IsDiskNode = ClusterNodes == [] orelse lists:member(node(), ClusterNodes),
+ IsDiskNode = should_be_disc_node(ClusterNodes),
WasDiskNode = is_disc_node(),
case mnesia:change_config(extra_db_nodes, ProperClusterNodes) of
{ok, Nodes} ->
@@ -480,7 +496,6 @@ init_db(ClusterNodes, Force, SecondaryPostMnesiaFun) ->
false -> {ram, ram_copies}
end,
ok = wait_for_replicated_tables(),
- assert_tables_copy_type(CopyTypeAlt),
ok = create_local_table_copy(schema, CopyTypeAlt),
ok = create_local_table_copies(CopyType),
ok = SecondaryPostMnesiaFun(),
@@ -549,6 +564,9 @@ is_disc_node() ->
%% disc node).
filelib:is_regular(filename:join(dir(), "rabbit_durable_exchange.DCD")).
+should_be_disc_node(ClusterNodes) ->
+ ClusterNodes == [] orelse lists:member(node(), ClusterNodes).
+
move_db() ->
mnesia:stop(),
MnesiaDir = filename:dirname(dir() ++ "/"),
@@ -612,41 +630,6 @@ copy_type_to_ram(TabDef) ->
table_has_copy_type(TabDef, DiscType) ->
lists:member(node(), proplists:get_value(DiscType, TabDef, [])).
-assert_tables_copy_type(CopyTypeAlt) ->
- case mnesia:table_info(schema, storage_type) of
- CopyTypeAlt -> ok;
- _ -> case mnesia:change_table_copy_type(schema, node(), CopyTypeAlt) of
- {aborted, {"Disc resident tables", _, _}} -> ok;
- {atomic, ok} -> ok;
- E -> exit({'node_conversion_failed', E})
- end
- end,
- lists:foreach(
- fun({Tab, TabDef}) ->
- HasDiscCopies = table_has_copy_type(TabDef, disc_copies),
- HasDiscOnlyCopies = table_has_copy_type(TabDef, disc_only_copies),
- StorageType = if HasDiscCopies -> disc_copies;
- HasDiscOnlyCopies -> disc_only_copies;
- true -> ram_copies
- end,
- StorageType1 = if CopyTypeAlt =:= disc_copies -> StorageType;
- true -> ram_copies
- end,
- case mnesia:table_info(Tab, storage_type) of
- StorageType1 -> ok;
- unknown -> ok;
- _ ->
- {atomic, ok} = mnesia:change_table_copy_type(
- Tab, node(), StorageType1)
- end
- end, table_definitions()),
- case mnesia:table_info(schema, storage_type) of
- CopyTypeAlt -> ok;
- _ ->
- {atomic, ok} = mnesia:change_table_copy_type(
- schema, node(), CopyTypeAlt)
- end.
-
create_local_table_copies(Type) ->
lists:foreach(
fun ({Tab, TabDef}) ->
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index af201120..0c1a04b2 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -1066,6 +1066,10 @@ test_cluster_management2(SecondaryNode) ->
{error, {no_running_cluster_nodes, _, _}} =
control_action(reset, []),
+ %% attempt to change type when no other node is alive
+ {error, {no_running_cluster_nodes, _, _}} =
+ control_action(cluster, [SecondaryNodeS]),
+
%% leave system clustered, with the secondary node as a ram node
ok = control_action(force_reset, []),
ok = control_action(start_app, []),