aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mnesia/src')
-rw-r--r--lib/mnesia/src/mnesia.appup.src70
-rw-r--r--lib/mnesia/src/mnesia_controller.erl64
-rw-r--r--lib/mnesia/src/mnesia_dumper.erl4
-rw-r--r--lib/mnesia/src/mnesia_lib.erl40
-rw-r--r--lib/mnesia/src/mnesia_locker.erl2
-rw-r--r--lib/mnesia/src/mnesia_log.erl2
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl3
-rw-r--r--lib/mnesia/src/mnesia_recover.erl42
-rw-r--r--lib/mnesia/src/mnesia_registry.erl4
-rw-r--r--lib/mnesia/src/mnesia_schema.erl33
-rw-r--r--lib/mnesia/src/mnesia_subscr.erl43
-rw-r--r--lib/mnesia/src/mnesia_text.erl4
-rw-r--r--lib/mnesia/src/mnesia_tm.erl4
13 files changed, 195 insertions, 120 deletions
diff --git a/lib/mnesia/src/mnesia.appup.src b/lib/mnesia/src/mnesia.appup.src
index b3b9297db2..22ef5178a7 100644
--- a/lib/mnesia/src/mnesia.appup.src
+++ b/lib/mnesia/src/mnesia.appup.src
@@ -1,69 +1,13 @@
%% -*- erlang -*-
{"%VSN%",
- [
- {"4.4.12",
- [
- {update, mnesia, soft, soft_purge, soft_purge, []},
- {update, mnesia_loader, soft, soft_purge, soft_purge, []},
- {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
- {update, mnesia_tm, soft, soft_purge, soft_purge, []}
- ]
- },
- {"4.4.11",
- [
- {update, mnesia, soft, soft_purge, soft_purge, []},
- {update, mnesia_loader, soft, soft_purge, soft_purge, []},
- {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
- {update, mnesia_tm, soft, soft_purge, soft_purge, []},
- {update, mnesia_locker, soft, soft_purge, soft_purge, []},
- {update, mnesia_controller, soft, soft_purge, soft_purge, []}
- ]
- },
- {"4.4.10",
- [
- {update, mnesia, soft, soft_purge, soft_purge, []},
- {update, mnesia_loader, soft, soft_purge, soft_purge, []},
- {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
- {update, mnesia_tm, soft, soft_purge, soft_purge, []},
- {update, mnesia_locker, soft, soft_purge, soft_purge, []},
- {update, mnesia_controller, soft, soft_purge, soft_purge, []}
- ]
- },
- {"4.4.9", [{restart_application, mnesia}]},
- {"4.4.8", [{restart_application, mnesia}]},
- {"4.4.7", [{restart_application, mnesia}]}
+ [
+ {"4.4.15",[
+ {update, mnesia_dumper, soft, soft_purge, soft_purge, []}
+ ]}
],
[
- {"4.4.12",
- [
- {update, mnesia, soft, soft_purge, soft_purge, []},
- {update, mnesia_loader, soft, soft_purge, soft_purge, []},
- {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
- {update, mnesia_tm, soft, soft_purge, soft_purge, []}
- ]
- },
- {"4.4.11",
- [
- {update, mnesia, soft, soft_purge, soft_purge, []},
- {update, mnesia_loader, soft, soft_purge, soft_purge, []},
- {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
- {update, mnesia_tm, soft, soft_purge, soft_purge, []},
- {update, mnesia_locker, soft, soft_purge, soft_purge, []},
- {update, mnesia_controller, soft, soft_purge, soft_purge, []}
- ]
- },
- {"4.4.10",
- [
- {update, mnesia, soft, soft_purge, soft_purge, []},
- {update, mnesia_loader, soft, soft_purge, soft_purge, []},
- {update, mnesia_monitor, soft, soft_purge, soft_purge, []},
- {update, mnesia_tm, soft, soft_purge, soft_purge, []},
- {update, mnesia_locker, soft, soft_purge, soft_purge, []},
- {update, mnesia_controller, soft, soft_purge, soft_purge, []}
- ]
- },
- {"4.4.9", [{restart_application, mnesia}]},
- {"4.4.8", [{restart_application, mnesia}]},
- {"4.4.7", [{restart_application, mnesia}]}
+ {"4.4.15",[
+ {update, mnesia_dumper, soft, soft_purge, soft_purge, []}
+ ]}
]
}.
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 9bc480e619..021be8af2a 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. 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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -52,6 +52,7 @@
async_dump_log/1,
sync_dump_log/1,
connect_nodes/1,
+ connect_nodes/2,
wait_for_schema_commit_lock/0,
release_schema_commit_lock/0,
create_table/1,
@@ -94,9 +95,11 @@
load_and_reply/2,
send_and_reply/2,
wait_for_tables_init/2,
- connect_nodes2/2
+ connect_nodes2/3
]).
+-compile({no_auto_import,[error/2]}).
+
-import(mnesia_lib, [set/2, add/2]).
-import(mnesia_lib, [fatal/2, error/2, verbose/2, dbg_out/2]).
@@ -420,12 +423,15 @@ try_schedule_late_disc_load(Tabs, Reason, MsgTag) ->
[[Tabs, Reason, MsgTag], AbortReason])
end.
-connect_nodes(Ns) ->
+connect_nodes(Ns) ->
+ connect_nodes(Ns, fun default_merge/1).
+
+connect_nodes(Ns, UserFun) ->
case mnesia:system_info(is_running) of
no ->
{error, {node_not_running, node()}};
yes ->
- Pid = spawn_link(?MODULE,connect_nodes2,[self(),Ns]),
+ Pid = spawn_link(?MODULE,connect_nodes2,[self(),Ns, UserFun]),
receive
{?MODULE, Pid, Res, New} ->
case Res of
@@ -443,7 +449,7 @@ connect_nodes(Ns) ->
end
end.
-connect_nodes2(Father, Ns) ->
+connect_nodes2(Father, Ns, UserFun) ->
Current = val({current, db_nodes}),
abcast([node()|Ns], {merging_schema, node()}),
{NewC, OldC} = mnesia_recover:connect_nodes(Ns),
@@ -451,7 +457,7 @@ connect_nodes2(Father, Ns) ->
New1 = mnesia_lib:intersect(Ns, Connected),
New = New1 -- Current,
process_flag(trap_exit, true),
- Res = try_merge_schema(New),
+ Res = try_merge_schema(New, UserFun),
Msg = {schema_is_merged, [], late_merge, []},
multicall([node()|Ns], Msg),
After = val({current, db_nodes}),
@@ -465,7 +471,7 @@ connect_nodes2(Father, Ns) ->
merge_schema() ->
AllNodes = mnesia_lib:all_nodes(),
- case try_merge_schema(AllNodes) of
+ case try_merge_schema(AllNodes, fun default_merge/1) of
ok ->
schema_is_merged();
{aborted, {throw, Str}} when is_list(Str) ->
@@ -474,8 +480,11 @@ merge_schema() ->
fatal("Failed to merge schema: ~p~n", [Else])
end.
-try_merge_schema(Nodes) ->
- case mnesia_schema:merge_schema() of
+default_merge(F) ->
+ F([]).
+
+try_merge_schema(Nodes, UserFun) ->
+ case mnesia_schema:merge_schema(UserFun) of
{atomic, not_merged} ->
%% No more nodes that we need to merge the schema with
ok;
@@ -488,11 +497,11 @@ try_merge_schema(Nodes) ->
im_running(OldFriends, NewFriends),
im_running(NewFriends, OldFriends),
- try_merge_schema(Nodes);
+ try_merge_schema(Nodes, UserFun);
{atomic, {"Cannot get cstructs", Node, Reason}} ->
dbg_out("Cannot get cstructs, Node ~p ~p~n", [Node, Reason]),
timer:sleep(1000), % Avoid a endless loop look alike
- try_merge_schema(Nodes);
+ try_merge_schema(Nodes, UserFun);
Other ->
Other
end.
@@ -1842,17 +1851,20 @@ reply(ReplyTo, Reply) ->
add_worker(Worker = #dump_log{}, State) ->
InitBy = Worker#dump_log.initiated_by,
Queue = State#state.dumper_queue,
- case lists:keymember(InitBy, #dump_log.initiated_by, Queue) of
- true when Worker#dump_log.opt_reply_to == undefined ->
- %% The same threshold has been exceeded again,
- %% before we have had the possibility to
- %% process the older one.
- DetectedBy = {dump_log, InitBy},
- Event = {mnesia_overload, DetectedBy},
- mnesia_lib:report_system_event(Event);
- _ ->
- ignore
- end,
+ Status =
+ case lists:keymember(InitBy, #dump_log.initiated_by, Queue) of
+ true when Worker#dump_log.opt_reply_to == undefined ->
+ %% The same threshold has been exceeded again,
+ %% before we have had the possibility to
+ %% process the older one.
+ DetectedBy = {dump_log, InitBy},
+ Event = {mnesia_overload, DetectedBy},
+ mnesia_lib:report_system_event(Event),
+ true;
+ _ ->
+ false
+ end,
+ mnesia_recover:log_dump_overload(Status),
Queue2 = Queue ++ [Worker],
State2 = State#state{dumper_queue = Queue2},
opt_start_worker(State2);
diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl
index f669d009c6..644133cf5d 100644
--- a/lib/mnesia/src/mnesia_dumper.erl
+++ b/lib/mnesia/src/mnesia_dumper.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. 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
@@ -643,7 +643,7 @@ insert_op(Tid, _, {op, create_table, TabDef}, InPlace, InitBy) ->
true -> ignore;
false ->
mnesia_log:open_log(temp,
- mnesia_log:dcl_log_header(),
+ mnesia_log:dcd_log_header(),
Dcd,
false,
false,
diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl
index dba808e66e..3da3dd2f5c 100644
--- a/lib/mnesia/src/mnesia_lib.erl
+++ b/lib/mnesia/src/mnesia_lib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. 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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -113,6 +113,9 @@
mkcore/1,
not_active_here/1,
other_val/2,
+ overload_read/0,
+ overload_read/1,
+ overload_set/2,
pad_name/3,
random_time/2,
read_counter/1,
@@ -551,6 +554,33 @@ cs_to_nodes(Cs) ->
Cs#cstruct.disc_only_copies ++
Cs#cstruct.disc_copies ++
Cs#cstruct.ram_copies.
+
+overload_types() ->
+ [mnesia_tm, mnesia_dump_log].
+
+valid_overload_type(T) ->
+ case lists:member(T, overload_types()) of
+ false ->
+ erlang:error(bad_type);
+ true ->
+ true
+ end.
+
+overload_set(Type, Bool) when is_boolean(Bool) ->
+ valid_overload_type(Type),
+ set({overload, Type}, Bool).
+
+overload_read() ->
+ [{T, overload_read(T)} || T <- overload_types()].
+
+overload_read(T) ->
+ case ?catch_val({overload, T}) of
+ {'EXIT',_} ->
+ valid_overload_type(T),
+ false;
+ Flag when is_boolean(Flag) ->
+ Flag
+ end.
dist_coredump() ->
dist_coredump(all_nodes()).
diff --git a/lib/mnesia/src/mnesia_locker.erl b/lib/mnesia/src/mnesia_locker.erl
index cfa3f171b2..6b5770d91e 100644
--- a/lib/mnesia/src/mnesia_locker.erl
+++ b/lib/mnesia/src/mnesia_locker.erl
@@ -49,6 +49,8 @@
system_code_change/4
]).
+-compile({no_auto_import,[error/2]}).
+
-include("mnesia.hrl").
-import(mnesia_lib, [dbg_out/2, error/2, verbose/2]).
diff --git a/lib/mnesia/src/mnesia_log.erl b/lib/mnesia/src/mnesia_log.erl
index 00ec4740ee..11b792026e 100644
--- a/lib/mnesia/src/mnesia_log.erl
+++ b/lib/mnesia/src/mnesia_log.erl
@@ -182,6 +182,8 @@
]).
+-compile({no_auto_import,[error/2]}).
+
-include("mnesia.hrl").
-import(mnesia_lib, [val/1, dir/1]).
-import(mnesia_lib, [exists/1, fatal/2, error/2, dbg_out/2]).
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index 5df5df4969..b6eda9ad3a 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -70,6 +70,8 @@
negotiate_protocol_impl/2
]).
+-compile({no_auto_import,[error/2]}).
+
-import(mnesia_lib, [dbg_out/2, verbose/2, error/2, fatal/2, set/2]).
-include("mnesia.hrl").
@@ -256,6 +258,7 @@ init([Parent]) ->
?ets_new_table(mnesia_gvar, [set, public, named_table]),
?ets_new_table(mnesia_stats, [set, public, named_table]),
set(subscribers, []),
+ set(activity_subscribers, []),
mnesia_lib:verbose("~p starting: ~p~n", [?MODULE, self()]),
Version = mnesia:system_info(version),
set(version, Version),
diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl
index 6c53c2e752..7435b6896a 100644
--- a/lib/mnesia/src/mnesia_recover.erl
+++ b/lib/mnesia/src/mnesia_recover.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -36,6 +36,7 @@
incr_trans_tid_serial/0,
init/0,
log_decision/1,
+ log_dump_overload/1,
log_master_nodes/3,
log_mnesia_down/1,
log_mnesia_up/1,
@@ -61,6 +62,7 @@
code_change/3
]).
+-compile({no_auto_import,[error/2]}).
-include("mnesia.hrl").
-import(mnesia_lib, [set/2, verbose/2, error/2, fatal/2]).
@@ -70,6 +72,7 @@
unclear_decision,
unclear_waitfor,
tm_queue_len = 0,
+ log_dump_overload = false,
initiated = false,
early_msgs = []
}).
@@ -277,6 +280,9 @@ mnesia_down(Node) ->
cast({mnesia_down, Node})
end.
+log_dump_overload(Flag) when is_boolean(Flag) ->
+ cast({log_dump_overload, Flag}).
+
log_master_nodes(Args, UseDir, IsRunning) ->
if
IsRunning == yes ->
@@ -818,6 +824,12 @@ handle_cast({announce_all, Nodes}, State) ->
announce_all(Nodes),
{noreply, State};
+handle_cast({log_dump_overload, Flag}, State) when is_boolean(Flag) ->
+ Prev = State#state.log_dump_overload,
+ Overload = Prev orelse Flag,
+ mnesia_lib:overload_set(mnesia_dump_log, Overload),
+ {noreply, State#state{log_dump_overload = Flag}};
+
handle_cast(Msg, State) ->
error("~p got unexpected cast: ~p~n", [?MODULE, Msg]),
{noreply, State}.
@@ -851,12 +863,14 @@ handle_info(check_overload, S) ->
Len > Threshold, Prev > Threshold ->
What = {mnesia_tm, message_queue_len, [Prev, Len]},
mnesia_lib:report_system_event({mnesia_overload, What}),
+ mnesia_lib:overload_set(mnesia_tm, true),
{noreply, S#state{tm_queue_len = 0}};
Len > Threshold ->
{noreply, S#state{tm_queue_len = Len}};
true ->
+ mnesia_lib:overload_set(mnesia_tm, false),
{noreply, S#state{tm_queue_len = 0}}
end;
undefined ->
@@ -905,7 +919,23 @@ terminate(Reason, State) ->
%% Purpose: Upgrade process when its code is to be changed
%% Returns: {ok, NewState}
%%----------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
+code_change(_OldVsn, {state,
+ Supervisor,
+ Unclear_pid,
+ Unclear_decision,
+ Unclear_waitfor,
+ Tm_queue_len,
+ Initiated,
+ Early_msgs
+ }, _Extra) ->
+ {ok, #state{supervisor = Supervisor,
+ unclear_pid = Unclear_pid,
+ unclear_decision = Unclear_decision,
+ unclear_waitfor = Unclear_waitfor,
+ tm_queue_len = Tm_queue_len,
+ initiated = Initiated,
+ early_msgs = Early_msgs}};
+code_change(_OldVsn, #state{} = State, _Extra) ->
{ok, State}.
%%%----------------------------------------------------------------------
diff --git a/lib/mnesia/src/mnesia_registry.erl b/lib/mnesia/src/mnesia_registry.erl
index 9805d48697..202689ae5e 100644
--- a/lib/mnesia/src/mnesia_registry.erl
+++ b/lib/mnesia/src/mnesia_registry.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. 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
@@ -65,6 +65,8 @@
%%%----------------------------------------------------------------------
%% External exports
+%% Avoid warning for local function max/2 clashing with autoimported BIF.
+-compile({no_auto_import,[max/2]}).
-export([start_dump/2, start_restore/2]).
-export([create_table/1, create_table/2]).
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index 354431a296..17e570b881 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. 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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -62,6 +62,7 @@
list2cs/1,
lock_schema/0,
merge_schema/0,
+ merge_schema/1,
move_table/3,
opt_create_dir/2,
prepare_commit/3,
@@ -2650,10 +2651,16 @@ make_dump_tables([]) ->
%% Merge the local schema with the schema on other nodes
merge_schema() ->
- schema_transaction(fun() -> do_merge_schema() end).
+ schema_transaction(fun() -> do_merge_schema([]) end).
+
+merge_schema(UserFun) ->
+ schema_transaction(fun() -> UserFun(fun(Arg) -> do_merge_schema(Arg) end) end).
-do_merge_schema() ->
+
+do_merge_schema(LockTabs0) ->
{_Mod, Tid, Ts} = get_tid_ts_and_lock(schema, write),
+ LockTabs = [{T, tab_to_nodes(T)} || T <- LockTabs0],
+ [get_tid_ts_and_lock(T,write) || {T,_} <- LockTabs],
Connected = val(recover_nodes),
Running = val({current, db_nodes}),
Store = Ts#tidstore.store,
@@ -2665,9 +2672,12 @@ do_merge_schema() ->
mnesia:abort({bad_commit, {missing_lock, Miss}})
end,
case Connected -- Running of
- [Node | _] ->
+ [Node | _] = OtherNodes ->
%% Time for a schema merging party!
mnesia_locker:wlock_no_exist(Tid, Store, schema, [Node]),
+ [mnesia_locker:wlock_no_exist(
+ Tid, Store, T, mnesia_lib:intersect(Ns, OtherNodes))
+ || {T,Ns} <- LockTabs],
case rpc:call(Node, mnesia_controller, get_cstructs, []) of
{cstructs, Cstructs, RemoteRunning1} ->
LockedAlready = Running ++ [Node],
@@ -2681,6 +2691,9 @@ do_merge_schema() ->
end,
NeedsLock = RemoteRunning -- LockedAlready,
mnesia_locker:wlock_no_exist(Tid, Store, schema, NeedsLock),
+ [mnesia_locker:wlock_no_exist(Tid, Store, T,
+ mnesia_lib:intersect(Ns,NeedsLock))
+ || {T,Ns} <- LockTabs],
{value, SchemaCs} =
lists:keysearch(schema, #cstruct.name, Cstructs),
@@ -2714,6 +2727,10 @@ do_merge_schema() ->
not_merged
end.
+tab_to_nodes(Tab) when is_atom(Tab) ->
+ Cs = val({Tab, cstruct}),
+ mnesia_lib:cs_to_nodes(Cs).
+
make_merge_schema(Node, [Cs | Cstructs]) ->
Ops = do_make_merge_schema(Node, Cs),
Ops ++ make_merge_schema(Node, Cstructs);
diff --git a/lib/mnesia/src/mnesia_subscr.erl b/lib/mnesia/src/mnesia_subscr.erl
index afd1704dec..415c69d508 100644
--- a/lib/mnesia/src/mnesia_subscr.erl
+++ b/lib/mnesia/src/mnesia_subscr.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -30,7 +30,8 @@
subscribers/0,
report_table_event/4,
report_table_event/5,
- report_table_event/6
+ report_table_event/6,
+ report_activity/1
]).
%% gen_server callbacks
@@ -42,6 +43,8 @@
code_change/3
]).
+-compile({no_auto_import,[error/2]}).
+
-include("mnesia.hrl").
-import(mnesia_lib, [error/2]).
@@ -91,6 +94,8 @@ set_debug_level(Level, OldEnv) ->
subscribe(ClientPid, system) ->
change_subscr(activate, ClientPid, system);
+subscribe(ClientPid, activity) ->
+ change_subscr(activate, ClientPid, activity);
subscribe(ClientPid, {table, Tab}) ->
change_subscr(activate, ClientPid, {table, Tab, simple});
subscribe(ClientPid, {table, Tab, simple}) ->
@@ -102,6 +107,8 @@ subscribe(_ClientPid, What) ->
unsubscribe(ClientPid, system) ->
change_subscr(deactivate, ClientPid, system);
+unsubscribe(ClientPid, activity) ->
+ change_subscr(deactivate, ClientPid, activity);
unsubscribe(ClientPid, {table, Tab}) ->
change_subscr(deactivate, ClientPid, {table, Tab, simple});
unsubscribe(ClientPid, {table, Tab, simple}) ->
@@ -120,6 +127,15 @@ change_subscr(Kind, ClientPid, What) ->
subscribers() ->
[whereis(mnesia_event) | mnesia_lib:val(subscribers)].
+report_activity({dirty, _pid}) ->
+ ok;
+report_activity(Tid) ->
+ case ?catch_val(activity_subscribers) of
+ {'EXIT', _} -> ok;
+ Subscribers ->
+ deliver(Subscribers, {mnesia_activity_event, {complete, Tid}})
+ end.
+
report_table_event(Tab, Tid, Obj, Op) ->
case ?catch_val({Tab, commit_work}) of
{'EXIT', _} -> ok;
@@ -300,6 +316,9 @@ code_change(_OldVsn, State, _Extra) ->
do_change({activate, ClientPid, system}, SubscrTab) when is_pid(ClientPid) ->
Var = subscribers,
activate(ClientPid, system, Var, subscribers(), SubscrTab);
+do_change({activate, ClientPid, activity}, SubscrTab) when is_pid(ClientPid) ->
+ Var = activity_subscribers,
+ activate(ClientPid, activity, Var, mnesia_lib:val(Var), SubscrTab);
do_change({activate, ClientPid, {table, Tab, How}}, SubscrTab) when is_pid(ClientPid) ->
case ?catch_val({Tab, where_to_read}) of
Node when Node == node() ->
@@ -313,6 +332,9 @@ do_change({activate, ClientPid, {table, Tab, How}}, SubscrTab) when is_pid(Clien
do_change({deactivate, ClientPid, system}, SubscrTab) ->
Var = subscribers,
deactivate(ClientPid, system, Var, SubscrTab);
+do_change({deactivate, ClientPid, activity}, SubscrTab) ->
+ Var = activity_subscribers,
+ deactivate(ClientPid, activity, Var, SubscrTab);
do_change({deactivate, ClientPid, {table, Tab, How}}, SubscrTab) ->
Var = {Tab, commit_work},
deactivate(ClientPid, {table, Tab, How}, Var, SubscrTab);
@@ -345,7 +367,7 @@ do_change(_, _) ->
activate(ClientPid, What, Var, OldSubscribers, SubscrTab) ->
Old =
- if Var == subscribers ->
+ if Var == subscribers orelse Var == activity_subscribers ->
OldSubscribers;
true ->
case lists:keysearch(subscribers, 1, OldSubscribers) of
@@ -379,6 +401,9 @@ activate(ClientPid, What, Var, OldSubscribers, SubscrTab) ->
add_subscr(subscribers, _What, Pid) ->
mnesia_lib:add(subscribers, Pid),
{ok, node()};
+add_subscr(activity_subscribers, _What, Pid) ->
+ mnesia_lib:add(activity_subscribers, Pid),
+ {ok, node()};
add_subscr({Tab, commit_work}, What, Pid) ->
Commit = mnesia_lib:val({Tab, commit_work}),
case lists:keysearch(subscribers, 1, Commit) of
@@ -427,6 +452,8 @@ deactivate(ClientPid, What, Var, SubscrTab) ->
del_subscr(subscribers, _What, Pid) ->
mnesia_lib:del(subscribers, Pid);
+del_subscr(activity_subscribers, _What, Pid) ->
+ mnesia_lib:del(activity_subscribers, Pid);
del_subscr({Tab, commit_work}, What, Pid) ->
Commit = mnesia_lib:val({Tab, commit_work}),
case lists:keysearch(subscribers, 1, Commit) of
@@ -473,6 +500,8 @@ do_handle_exit([{ClientPid, What} | Tail]) ->
case What of
system ->
del_subscr(subscribers, What, ClientPid);
+ activity ->
+ del_subscr(activity_subscribers, What, ClientPid);
{_, Tab, _Level} ->
del_subscr({Tab, commit_work}, What, ClientPid)
end,
diff --git a/lib/mnesia/src/mnesia_text.erl b/lib/mnesia/src/mnesia_text.erl
index f1a28bf43d..ab1362f6b6 100644
--- a/lib/mnesia/src/mnesia_text.erl
+++ b/lib/mnesia/src/mnesia_text.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. 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
@@ -20,6 +20,8 @@
%%
-module(mnesia_text).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([parse/1, file/1, load_textfile/1, dump_to_textfile/1]).
load_textfile(File) ->
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index d42109c3da..f3ffac5493 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -1733,7 +1733,9 @@ do_commit(Tid, C, DumperMode) ->
R = do_snmp(Tid, C#commit.snmp),
R2 = do_update(Tid, ram_copies, C#commit.ram_copies, R),
R3 = do_update(Tid, disc_copies, C#commit.disc_copies, R2),
- do_update(Tid, disc_only_copies, C#commit.disc_only_copies, R3).
+ R4 = do_update(Tid, disc_only_copies, C#commit.disc_only_copies, R3),
+ mnesia_subscr:report_activity(Tid),
+ R4.
%% Update the items
do_update(Tid, Storage, [Op | Ops], OldRes) ->