[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
novices.
</aside>

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.

-Scott

--- 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 1.1.1.1
diff -u -r1.1.1.1 mnesia_frag.erl
--- mnesia_frag.erl	6 Sep 2006 23:33:39 -0000	1.1.1.1
+++ 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