[erlang-questions] Bug in code and/or documentation of mnesia:change_table_frag/2

Scott Lystig Fritchie fritchie@REDACTED
Wed Dec 6 01:00:12 CET 2006

Greetings.  I believe there's a bug in the code and/or docs for
mnesia:change_table_frag/2.  I've been bitten by this in R10B-9.  It's
possible to work-around the bug, but I figure that submitting a
suggested fix/patch can't hurt.  :-)

<aside> I realize that table fragmentation wasn't part of the original
Mnesia implementation ... but it would be nice if more functions
related to fragmentation, such as mnesia:change_table_frag/2, were
documented in the 'mnesia' reference guide with their cousins.  Hiding
docs only in the User's Guide (Section 5.3) isn't friendly to Mnesia

The heart of My Problem is that the list of nodes given to
mnesia:change_table_frag(Table, {add_frag, ListOfNodes}) must all be
up and rpc'able.  If a down node N exists in ListOfNodes, the behavior
of mnesia:change_table_frag/2 will depend on N's position in the
list(*).  (Assume that the fragments of Table have 1 replica each.)

  mnesia:change_table_frag(Table, {add_frag, [node(), foo@REDACTED]})

... will succeed.

  mnesia:change_table_frag(Table, {add_frag, [foo@REDACTED, node()]})

... will fail.  It fails despite the fact that the list contains
enough hosts to successfully create the necessary # of replicas for
the new fragment.

If this behavior is The Way It Really Must Be For Backward
Compatibility, then I suggest this: that the description of 'add_frag'
in Section 5.3.3 ("Management of Fragmented Tables") explicitly say
that all nodes must be up, running, reachable, and happy.

If this (unwelcome, IMHO) behavior can be changed, then I suggest the
small patch below.  I'd come up with a bigger patch, but then I
realized I was blind and boiled it down to this.  The patched function
is mnesia_frag:make_add_frag/2.  mnesia_frag:make_add_frag/2 seems
identical in R11B-2.


--- snip --- snip --- snip --- snip --- snip --- snip --- snip ---

Index: mnesia_frag.erl
RCS file: /export/cvs/src/third-party/mnesia/src/src/mnesia_frag.erl,v
retrieving revision
diff -u -r1.1.1.1 mnesia_frag.erl
--- mnesia_frag.erl	6 Sep 2006 23:33:39 -0000
+++ mnesia_frag.erl	5 Dec 2006 23:37:23 -0000
@@ -727,14 +727,17 @@
 		       ram_copies = [],
 		       disc_copies = [],
 		       disc_only_copies = []},
-    {NewCs2, _, _} = set_frag_nodes(NR, ND, NDO, NewCs, SortedNs, []),
+    SortedNs2 =
+	lists:filter(fun(N) -> lists:member(N, val({current, db_nodes})) end,
+		     SortedNs),
+    {NewCs2, _, _} = set_frag_nodes(NR, ND, NDO, NewCs, SortedNs2, []),
     [NewOp] = mnesia_schema:make_create_table(NewCs2),
     SplitOps = split(Tab, FH2, FromIndecies, FragNames, []),
     Cs2 = replace_frag_hash(Cs, FH2),
     TabDef = mnesia_schema:cs2list(Cs2),
-    BaseOp = {op, change_table_frag, {add_frag, SortedNs}, TabDef},
+    BaseOp = {op, change_table_frag, {add_frag, SortedNs2}, TabDef},
     [BaseOp, NewOp | SplitOps].

More information about the erlang-questions mailing list