aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia/src/mnesia_schema.erl
diff options
context:
space:
mode:
authorUlf Wiger <ulf.wiger@erlang-solutions.com>2011-08-01 18:38:17 +0200
committerDan Gudmundsson <dgud@erlang.org>2011-09-15 15:34:18 +0200
commit43647249896ca972844796cdd8e23d485749a7ed (patch)
treecd2dc156a037b50d7daa29d6c309c2f638d13d82 /lib/mnesia/src/mnesia_schema.erl
parent2566dbcc68213fdd0aba0323dc43c7fa70a9bba0 (diff)
downloadotp-43647249896ca972844796cdd8e23d485749a7ed.tar.gz
otp-43647249896ca972844796cdd8e23d485749a7ed.tar.bz2
otp-43647249896ca972844796cdd8e23d485749a7ed.zip
[mnesia] Mnesia schema merge tested with 2 nodes, r13b04 -> r14b (dev)
The do_merge_schema function now converts cstructs from a remote node when it detects that they are different. In order to be compatible the other way around, mnesia_controller:get_cstructs() detects a remote caller, and converts the cstructs before sending them.
Diffstat (limited to 'lib/mnesia/src/mnesia_schema.erl')
-rw-r--r--lib/mnesia/src/mnesia_schema.erl26
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index fef72ad39c..e5cea16f0c 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -2733,7 +2733,8 @@ do_merge_schema(LockTabs0) ->
Tid, Store, T, mnesia_lib:intersect(Ns, OtherNodes))
|| {T,Ns} <- LockTabs],
case rpc:call(Node, mnesia_controller, get_cstructs, []) of
- {cstructs, Cstructs, RemoteRunning1} ->
+ {cstructs, Cstructs0, RemoteRunning1} ->
+ {Cstructs, DeleteFields} = normalize_remote_cstructs(Cstructs0, Node),
LockedAlready = Running ++ [Node],
{New, Old} = mnesia_recover:connect_nodes(RemoteRunning1),
RemoteRunning = mnesia_lib:intersect(New ++ Old, RemoteRunning1),
@@ -2754,19 +2755,20 @@ do_merge_schema(LockTabs0) ->
%% Announce that Node is running
A = [{op, announce_im_running, node(),
- cs2list(SchemaCs), Running, RemoteRunning}],
+ [{K,V} || {K,V} <- cs2list(SchemaCs),
+ not lists:member(K, DeleteFields)], Running, RemoteRunning}],
do_insert_schema_ops(Store, A),
-
+
%% Introduce remote tables to local node
do_insert_schema_ops(Store, make_merge_schema(Node, Cstructs)),
-
+
%% Introduce local tables to remote nodes
Tabs = val({schema, tables}),
Ops = [{op, merge_schema, get_create_list(T)}
|| T <- Tabs,
not lists:keymember(T, #cstruct.name, Cstructs)],
do_insert_schema_ops(Store, Ops),
-
+
%% Ensure that the txn will be committed on all nodes
NewNodes = RemoteRunning -- Running,
mnesia_lib:set(prepare_op, {announce_im_running,NewNodes}),
@@ -2782,6 +2784,18 @@ do_merge_schema(LockTabs0) ->
not_merged
end.
+normalize_remote_cstructs([#cstruct{}|_] = Cstructs, _) ->
+ {Cstructs, []};
+normalize_remote_cstructs([T|_] = Cstructs, Node) when element(1,T) == cstruct ->
+ Flds = [F || {F, _} <- rpc:call(Node, ?MODULE, cs2list, [T])],
+ DeleteFields = record_info(fields, cstruct) -- Flds,
+ NewCstructs = lists:map(
+ fun(Cs) ->
+ CsL = lists:zip(Flds, tl(tuple_to_list(Cs))),
+ #cstruct{} = list2cs(CsL)
+ end, Cstructs),
+ {NewCstructs, DeleteFields}.
+
tab_to_nodes(Tab) when is_atom(Tab) ->
Cs = val({Tab, cstruct}),
mnesia_lib:cs_to_nodes(Cs).
@@ -2919,7 +2933,7 @@ do_make_merge_schema(Node, RemoteCs) ->
%% Choose remote cstruct,
%% since it's the master
[{op, merge_schema, cs2list(RemoteCs)}];
-
+
true ->
Str = io_lib:format("Bad cookie in table definition"
" ~w: ~w = ~w, ~w = ~w~n",