diff options
author | Ulf Wiger <ulf.wiger@erlang-solutions.com> | 2011-08-01 18:38:17 +0200 |
---|---|---|
committer | Dan Gudmundsson <dgud@erlang.org> | 2011-09-15 15:34:18 +0200 |
commit | 43647249896ca972844796cdd8e23d485749a7ed (patch) | |
tree | cd2dc156a037b50d7daa29d6c309c2f638d13d82 /lib/mnesia/src/mnesia_schema.erl | |
parent | 2566dbcc68213fdd0aba0323dc43c7fa70a9bba0 (diff) | |
download | otp-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.erl | 26 |
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", |