aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mnesia/src')
-rw-r--r--lib/mnesia/src/mnesia.erl15
-rw-r--r--lib/mnesia/src/mnesia_checkpoint.erl7
-rw-r--r--lib/mnesia/src/mnesia_controller.erl7
-rw-r--r--lib/mnesia/src/mnesia_event.erl3
-rw-r--r--lib/mnesia/src/mnesia_loader.erl17
-rw-r--r--lib/mnesia/src/mnesia_log.erl4
-rw-r--r--lib/mnesia/src/mnesia_schema.erl16
-rw-r--r--lib/mnesia/src/mnesia_tm.erl3
8 files changed, 41 insertions, 31 deletions
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 9586adbf93..34efeca4fa 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -1409,8 +1409,14 @@ select_cont(Tid,_,State=#mnesia_select{tid=Tid,written=[]}) ->
select_state(dirty_sel_cont(State),State);
select_cont(Tid,_Ts,State=#mnesia_select{tid=Tid}) ->
trans_select(dirty_sel_cont(State), State);
-select_cont(_Tid2,_,#mnesia_select{tid=_Tid1}) -> % Missmatching tids
+select_cont(Tid2,_,#mnesia_select{tid=_Tid1})
+ when element(1,Tid2) == tid -> % Mismatching tids
abort(wrong_transaction);
+select_cont(Tid,Ts,State=#mnesia_select{}) ->
+ % Repair mismatching tids in non-transactional contexts
+ RepairedState = State#mnesia_select{tid = Tid, written = [],
+ spec = undefined, type = undefined},
+ select_cont(Tid,Ts,RepairedState);
select_cont(_,_,Cont) ->
abort({badarg, Cont}).
@@ -1876,9 +1882,10 @@ any_table_info(Tab, Item) when is_atom(Tab) ->
[] ->
abort({no_exists, Tab, Item});
Props ->
- lists:map(fun({setorbag, Type}) -> {type, Type};
- (Prop) -> Prop end,
- Props)
+ Rename = fun ({setorbag, Type}) -> {type, Type};
+ (Prop) -> Prop
+ end,
+ lists:sort(lists:map(Rename, Props))
end;
name ->
Tab;
diff --git a/lib/mnesia/src/mnesia_checkpoint.erl b/lib/mnesia/src/mnesia_checkpoint.erl
index 9eb939e8d3..fc626940b4 100644
--- a/lib/mnesia/src/mnesia_checkpoint.erl
+++ b/lib/mnesia/src/mnesia_checkpoint.erl
@@ -909,7 +909,7 @@ retainer_loop(Cp = #checkpoint_args{name=Name}) ->
retainer_loop(Cp2);
{From, {iter_end, Iter}} ->
- retainer_fixtable(Iter#iter.oid_tab, false),
+ ?SAFE(retainer_fixtable(Iter#iter.oid_tab, false)),
Iters = Cp#checkpoint_args.iterators -- [Iter],
reply(From, Name, ok),
retainer_loop(Cp#checkpoint_args{iterators = Iters});
@@ -971,7 +971,8 @@ do_stop(Cp) ->
unset({checkpoint, Name}),
lists:foreach(fun deactivate_tab/1, Cp#checkpoint_args.retainers),
Iters = Cp#checkpoint_args.iterators,
- lists:foreach(fun(I) -> retainer_fixtable(I#iter.oid_tab, false) end, Iters).
+ [?SAFE(retainer_fixtable(Tab, false)) || #iter{main_tab=Tab} <- Iters],
+ ok.
deactivate_tab(R) ->
Name = R#retainer.cp_name,
@@ -1151,7 +1152,7 @@ do_change_copy(Cp, Tab, FromType, ToType) ->
Cp#checkpoint_args{retainers = Rs, nodes = writers(Rs)}.
check_iter(From, Iter) when Iter#iter.pid == From ->
- retainer_fixtable(Iter#iter.oid_tab, false),
+ ?SAFE(retainer_fixtable(Iter#iter.oid_tab, false)),
false;
check_iter(_From, _Iter) ->
true.
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 4791e2e290..17b47c059e 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -1703,9 +1703,10 @@ add_active_replica(Tab, Node, Cs = #cstruct{}) ->
block_table(Tab) ->
Var = {Tab, where_to_commit},
- Old = val(Var),
- New = {blocked, Old},
- set(Var, New). % where_to_commit
+ case is_tab_blocked(val(Var)) of
+ {true, _} -> ok;
+ {false, W2C} -> set(Var, mark_blocked_tab(true, W2C))
+ end.
unblock_table(Tab) ->
call({unblock_table, Tab}).
diff --git a/lib/mnesia/src/mnesia_event.erl b/lib/mnesia/src/mnesia_event.erl
index 7320d381ea..6f7531245f 100644
--- a/lib/mnesia/src/mnesia_event.erl
+++ b/lib/mnesia/src/mnesia_event.erl
@@ -114,7 +114,8 @@ handle_table_event({Oper, Record, TransId}, State) ->
handle_system_event({mnesia_checkpoint_activated, _Checkpoint}, State) ->
{ok, State};
-handle_system_event({mnesia_checkpoint_deactivated, _Checkpoint}, State) ->
+handle_system_event({mnesia_checkpoint_deactivated, Checkpoint}, State) ->
+ report_error("Checkpoint '~p' has been deactivated, last table copy deleted.\n",[Checkpoint]),
{ok, State};
handle_system_event({mnesia_up, Node}, State) ->
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 71e5829c87..c710470a2c 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -342,9 +342,12 @@ spawned_receiver(ReplyTo,Tab,Storage,Cs, SenderPid,TabSize,DetsData, Init) ->
Done = do_init_table(Tab,Storage,Cs,
SenderPid,TabSize,DetsData,
ReplyTo, Init),
- ReplyTo ! {self(),Done},
- unlink(ReplyTo),
- unlink(whereis(mnesia_controller)),
+ try
+ ReplyTo ! {self(),Done},
+ unlink(ReplyTo),
+ unlink(whereis(mnesia_controller))
+ catch _:_ -> ok %% avoid error reports when stopping down mnesia
+ end,
exit(normal).
wait_on_load_complete(Pid) ->
@@ -916,9 +919,15 @@ send_packet(_N, _Pid, _Chunk, DataState) ->
finish_copy(Pid, Tab, Storage, RemoteS, NeedLock) ->
RecNode = node(Pid),
DatBin = dat2bin(Tab, Storage, RemoteS),
+ Node = node(Pid),
Trans =
fun() ->
NeedLock andalso mnesia:read_lock_table(Tab),
+ %% Check that receiver is still alive
+ receive {copier_done, Node} ->
+ throw(receiver_died)
+ after 0 -> ok
+ end,
A = val({Tab, access_mode}),
mnesia_controller:sync_and_block_table_whereabouts(Tab, RecNode, RemoteS, A),
cleanup_tab_copier(Pid, Storage, Tab),
@@ -927,7 +936,7 @@ finish_copy(Pid, Tab, Storage, RemoteS, NeedLock) ->
receive
{Pid, no_more} -> % Dont bother about the spurious 'more' message
no_more;
- {copier_done, Node} when Node == node(Pid)->
+ {copier_done, Node} ->
verbose("Tab receiver ~p crashed (more): ~p~n", [Tab, Node]),
receiver_died
end
diff --git a/lib/mnesia/src/mnesia_log.erl b/lib/mnesia/src/mnesia_log.erl
index 9536effd42..685d512acf 100644
--- a/lib/mnesia/src/mnesia_log.erl
+++ b/lib/mnesia/src/mnesia_log.erl
@@ -752,8 +752,8 @@ abort_write(B, What, Args, Reason) ->
Opaque = B#backup_args.opaque,
dbg_out("Failed to perform backup. M=~p:F=~p:A=~p -> ~p~n",
[Mod, What, Args, Reason]),
- try apply(Mod, abort_write, [Opaque]) of
- {ok, _Res} -> throw({error, Reason})
+ try {ok, _Res} = apply(Mod, abort_write, [Opaque]) of
+ _ -> throw({error, Reason})
catch _:Other ->
error("Failed to abort backup. ~p:~p~p -> ~p~n",
[Mod, abort_write, [Opaque], Other]),
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index 0e4017e4c3..bb5e38f7c1 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -952,19 +952,9 @@ get_index_plugins() ->
get_schema_user_property(mnesia_index_plugins).
get_schema_user_property(Key) ->
- Tab = schema,
- %% Must work reliably both within transactions and outside of transactions
- Res = case get(mnesia_activity_state) of
- undefined ->
- dirty_read_table_property(Tab, Key);
- _ ->
- do_read_table_property(Tab, Key)
- end,
- case Res of
- undefined ->
- [];
- {_, Types} ->
- Types
+ case dirty_read_table_property(schema, Key) of
+ undefined -> [];
+ {_, Types} -> Types
end.
get_ext_types_disc() ->
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index b116b48312..305bf14bcf 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -80,6 +80,7 @@ start() ->
init(Parent) ->
register(?MODULE, self()),
process_flag(trap_exit, true),
+ process_flag(message_queue_data, off_heap),
%% Initialize the schema
IgnoreFallback = mnesia_monitor:get_env(ignore_fallback_at_startup),
@@ -950,7 +951,7 @@ return_abort(Fun, Args, Reason) ->
if
Level == 1 ->
mnesia_locker:async_release_tid(Nodes, Tid),
- ?MODULE ! {delete_transaction, Tid},
+ ?SAFE(?MODULE ! {delete_transaction, Tid}),
erase(mnesia_activity_state),
flush_downs(),
?SAFE(unlink(whereis(?MODULE))),