aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mnesia')
-rw-r--r--lib/mnesia/src/mnesia_index.erl10
-rw-r--r--lib/mnesia/src/mnesia_loader.erl14
-rw-r--r--lib/mnesia/test/mnesia_evil_coverage_test.erl51
3 files changed, 67 insertions, 8 deletions
diff --git a/lib/mnesia/src/mnesia_index.erl b/lib/mnesia/src/mnesia_index.erl
index f9f3ce2ea4..6f9f575d93 100644
--- a/lib/mnesia/src/mnesia_index.erl
+++ b/lib/mnesia/src/mnesia_index.erl
@@ -301,7 +301,13 @@ make_ram_index(Tab, [Pos | Tail]) ->
add_ram_index(Tab, Pos) when is_integer(Pos) ->
verbose("Creating index for ~w ~n", [Tab]),
- Index = mnesia_monitor:mktab(mnesia_index, [bag, public]),
+ SetOrBag = val({Tab, setorbag}),
+ IndexType = case SetOrBag of
+ set -> duplicate_bag;
+ ordered_set -> duplicate_bag;
+ bag -> bag
+ end,
+ Index = mnesia_monitor:mktab(mnesia_index, [IndexType, public]),
Insert = fun(Rec, _Acc) ->
true = ?ets_insert(Index, {element(Pos, Rec), element(2, Rec)})
end,
@@ -309,7 +315,7 @@ add_ram_index(Tab, Pos) when is_integer(Pos) ->
true = ets:foldl(Insert, true, Tab),
mnesia_lib:db_fixtable(ram_copies, Tab, false),
mnesia_lib:set({Tab, {index, Pos}}, Index),
- add_index_info(Tab, val({Tab, setorbag}), {Pos, {ram, Index}});
+ add_index_info(Tab, SetOrBag, {Pos, {ram, Index}});
add_ram_index(_Tab, snmp) ->
ok.
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 4ba400fbbf..4afbea1cc2 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -487,7 +487,8 @@ finish_copy(Storage,Tab,Cs,SenderPid,DatBin,OrigTabRec) ->
subscr_receiver(TabRef = {_, Tab}, RecName) ->
receive
- {mnesia_table_event, {Op, Val, _Tid}} ->
+ {mnesia_table_event, {Op, Val, _Tid}}
+ when element(1, Val) =:= Tab ->
if
Tab == RecName ->
handle_event(TabRef, Op, Val);
@@ -496,6 +497,15 @@ subscr_receiver(TabRef = {_, Tab}, RecName) ->
end,
subscr_receiver(TabRef, RecName);
+ {mnesia_table_event, {Op, Val, _Tid}} when element(1, Val) =:= schema ->
+ %% clear_table is faked via two schema events
+ %% a schema record delete and a write
+ case Op of
+ delete -> handle_event(TabRef, clear_table, {Tab, all});
+ _ -> ok
+ end,
+ subscr_receiver(TabRef, RecName);
+
{'EXIT', Pid, Reason} ->
handle_exit(Pid, Reason),
subscr_receiver(TabRef, RecName)
diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl
index 64b61288ef..0df245b75d 100644
--- a/lib/mnesia/test/mnesia_evil_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -39,7 +39,7 @@ all() ->
db_node_lifecycle, evil_delete_db_node, start_and_stop,
checkpoint, table_lifecycle, storage_options,
add_copy_conflict,
- add_copy_when_going_down, replica_management,
+ add_copy_when_going_down, replica_management, clear_table_during_load,
schema_availability, local_content,
{group, table_access_modifications}, replica_location,
{group, table_sync}, user_properties, unsupp_user_props,
@@ -569,7 +569,50 @@ storage_options(Config) when is_list(Config) ->
?verify_mnesia(Nodes, []).
+clear_table_during_load(suite) -> [];
+clear_table_during_load(doc) ->
+ ["Clear table caused during load caused a schema entry in the actual tab"];
+clear_table_during_load(Config) when is_list(Config) ->
+ Nodes = [_, Node2] = ?acquire_nodes(2, Config ++ [{tc_timeout, timer:minutes(2)}]),
+ ?match({atomic,ok}, mnesia:create_table(cleartab, [{ram_copies, Nodes}])),
+ Tester = self(),
+ Bin = <<"Testingasdasd", 0:32000>>,
+ Fill = fun() -> [mnesia:write({cleartab, N, Bin}) || N <- lists:seq(1, 3000)], ok end,
+ ?match({atomic, ok}, mnesia:sync_transaction(Fill)),
+
+ StopAndStart = fun() ->
+ stopped = mnesia:stop(),
+ Tester ! {self(), stopped},
+ receive start_node -> ok end,
+ ok = mnesia:start(),
+ ok = mnesia:wait_for_tables([cleartab], 2000),
+ lists:foreach(fun({cleartab,_,_}) -> ok;
+ (What) -> Tester ! {failed, What},
+ unlink(Tester),
+ exit(foo)
+ end,
+ ets:tab2list(cleartab)),
+ Tester ! {self(), ok},
+ normal
+ end,
+ Test = fun(N) ->
+ Pid = spawn_link(Node2, StopAndStart),
+ receive {Pid, stopped} -> ok end,
+ Pid ! start_node,
+ timer:sleep(N*10),
+ {atomic, ok} = mnesia:clear_table(cleartab),
+ receive
+ {Pid, ok} -> ok;
+ {failed, What} ->
+ io:format("Failed in ~p tries, with ~p~n",[N, What]),
+ exit({error, What});
+ {'EXIT', Pid, Reason} ->
+ exit({died, Reason})
+ end
+ end,
+ [Test(N) || N <- lists:seq(1, 10)],
+ ?verify_mnesia(Nodes, []).
add_copy_conflict(suite) -> [];
@@ -599,7 +642,7 @@ add_copy_conflict(Config) when is_list(Config) ->
mnesia_controller:unblock_controller(),
?match_receive({test, {atomic,ok}}),
-
+ ?match(ok, mnesia:wait_for_tables([a,b], 3000)),
?verify_mnesia(Nodes, []),
?cleanup(1, Config).
@@ -635,7 +678,7 @@ add_copy_when_going_down(Config) ->
end,
_Lock = spawn(fun() -> mnesia:transaction(WriteAndWait) end),
Tester = self(),
- spawn_link(fun() -> Res = rpc:call(Node2,mnesia, add_table_copy,
+ spawn_link(fun() -> Res = rpc:call(Node2, mnesia, add_table_copy,
[a, Node2, ram_copies]),
Tester ! {test, Res}
end),