aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mnesia')
-rw-r--r--lib/mnesia/doc/src/Makefile13
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap2.xmlsrc2
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap5.xmlsrc8
-rw-r--r--lib/mnesia/doc/src/company.erl2
-rw-r--r--lib/mnesia/doc/src/company_o.erl2
-rw-r--r--lib/mnesia/doc/src/mnesia.xml243
-rw-r--r--lib/mnesia/doc/src/mnesia_frag_hash.xml16
-rw-r--r--lib/mnesia/doc/src/mnesia_registry.xml6
-rw-r--r--lib/mnesia/doc/src/notes.xml108
-rw-r--r--lib/mnesia/src/mnesia.erl32
-rw-r--r--lib/mnesia/src/mnesia.hrl6
-rw-r--r--lib/mnesia/src/mnesia_bup.erl10
-rw-r--r--lib/mnesia/src/mnesia_checkpoint.erl10
-rw-r--r--lib/mnesia/src/mnesia_controller.erl37
-rw-r--r--lib/mnesia/src/mnesia_dumper.erl19
-rw-r--r--lib/mnesia/src/mnesia_frag.erl7
-rw-r--r--lib/mnesia/src/mnesia_index.erl4
-rw-r--r--lib/mnesia/src/mnesia_late_loader.erl2
-rw-r--r--lib/mnesia/src/mnesia_lib.erl18
-rw-r--r--lib/mnesia/src/mnesia_loader.erl21
-rw-r--r--lib/mnesia/src/mnesia_locker.erl9
-rw-r--r--lib/mnesia/src/mnesia_log.erl2
-rw-r--r--lib/mnesia/src/mnesia_recover.erl8
-rw-r--r--lib/mnesia/src/mnesia_schema.erl11
-rw-r--r--lib/mnesia/src/mnesia_subscr.erl2
-rw-r--r--lib/mnesia/src/mnesia_text.erl2
-rw-r--r--lib/mnesia/src/mnesia_tm.erl24
-rw-r--r--lib/mnesia/test/mnesia_SUITE.erl2
-rw-r--r--lib/mnesia/test/mnesia_atomicity_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_bench_SUITE.erl2
-rw-r--r--lib/mnesia/test/mnesia_consistency_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_cost.erl2
-rw-r--r--lib/mnesia/test/mnesia_dirty_access_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_durability_test.erl109
-rw-r--r--lib/mnesia/test/mnesia_evil_coverage_test.erl107
-rw-r--r--lib/mnesia/test/mnesia_examples_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_frag_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_install_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl13
-rw-r--r--lib/mnesia/test/mnesia_majority_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_measure_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_nice_coverage_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_qlc_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_recovery_test.erl3
-rw-r--r--lib/mnesia/test/mnesia_registry_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_schema_recovery_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl8
-rw-r--r--lib/mnesia/test/mnesia_test_lib.hrl14
-rw-r--r--lib/mnesia/test/mnesia_trans_access_test.erl2
-rw-r--r--lib/mnesia/vsn.mk2
50 files changed, 625 insertions, 287 deletions
diff --git a/lib/mnesia/doc/src/Makefile b/lib/mnesia/doc/src/Makefile
index 82fcf66256..d9647fc081 100644
--- a/lib/mnesia/doc/src/Makefile
+++ b/lib/mnesia/doc/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2017. All Rights Reserved.
+# Copyright Ericsson AB 1997-2018. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -49,16 +49,18 @@ XML_PART_FILES = \
XML_CHAPTER_FILES = \
Mnesia_chap1.xml \
Mnesia_overview.xml \
+ Mnesia_chap8.xml \
+ notes.xml
+
+XML_CHAPTER_GEN_FILES = \
Mnesia_chap2.xml \
Mnesia_chap3.xml \
Mnesia_chap4.xml \
Mnesia_chap5.xml \
Mnesia_chap7.xml \
- Mnesia_chap8.xml \
Mnesia_App_A.xml \
Mnesia_App_B.xml \
- Mnesia_App_C.xml \
- notes.xml
+ Mnesia_App_C.xml
BOOK_FILES = book.xml
@@ -66,6 +68,8 @@ XML_FILES = \
$(BOOK_FILES) $(XML_CHAPTER_FILES) \
$(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES)
+XML_GEN_FILES = $(XML_CHAPTER_GEN_FILES:%=$(XMLDIR)/%)
+
GIF_FILES = \
company.gif
@@ -114,6 +118,7 @@ html: gifs $(HTML_REF_MAN_FILE)
clean clean_docs:
rm -rf $(HTMLDIR)/*
+ rm -rf $(XMLDIR)
rm -f $(MAN3DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
rm -f errs core *~
diff --git a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
index 914e0e509c..8135e14301 100644
--- a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
index 62759c624b..481e6651e6 100644
--- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -226,8 +226,10 @@
not known beforehand, all fragments are searched for
matching records.</p>
<p>Notice that in <c>ordered_set</c> tables, the records
- are ordered per fragment, and the the order is undefined in
- results returned by <c>select</c> and <c>match_object</c>.</p>
+ are ordered per fragment, and the order is undefined in
+ results returned by <c>select</c> and <c>match_object</c>,
+ as well as <c>first</c>, <c>next</c>, <c>prev</c> and
+ <c>last</c>.</p>
<p>The following code illustrates how a <c>Mnesia</c> table is
converted to be a fragmented table and how more fragments
are added later:</p>
diff --git a/lib/mnesia/doc/src/company.erl b/lib/mnesia/doc/src/company.erl
index 5a3b122394..fc04aa77bf 100644
--- a/lib/mnesia/doc/src/company.erl
+++ b/lib/mnesia/doc/src/company.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/doc/src/company_o.erl b/lib/mnesia/doc/src/company_o.erl
index 650b6cdeca..b4b3638596 100644
--- a/lib/mnesia/doc/src/company_o.erl
+++ b/lib/mnesia/doc/src/company_o.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index 621b6047ee..11b0b8e987 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -32,7 +32,7 @@
<rev></rev>
<file></file>
</header>
- <module>mnesia</module>
+ <module since="">mnesia</module>
<modulesummary>A distributed telecommunications DBMS</modulesummary>
<description>
@@ -183,7 +183,7 @@
<funcs>
<func>
- <name>abort(Reason) -> transaction abort</name>
+ <name since="">abort(Reason) -> transaction abort</name>
<fsummary>Terminates the current transaction.</fsummary>
<desc>
<p>Makes the transaction silently
@@ -195,7 +195,7 @@
</desc>
</func>
<func>
- <name>activate_checkpoint(Args) -> {ok,Name,Nodes} | {error,Reason}</name>
+ <name since="">activate_checkpoint(Args) -> {ok,Name,Nodes} | {error,Reason}</name>
<fsummary>Activates a checkpoint.</fsummary>
<desc>
<marker id="activate_checkpoint"></marker>
@@ -259,7 +259,7 @@
</desc>
</func>
<func>
- <name>activity(AccessContext, Fun [, Args]) -> ResultOfFun | exit(Reason)</name>
+ <name since="">activity(AccessContext, Fun [, Args]) -> ResultOfFun | exit(Reason)</name>
<fsummary>Executes <c>Fun</c> in <c>AccessContext</c>.</fsummary>
<desc>
<marker id="activity_2_3"></marker>
@@ -271,7 +271,7 @@
</desc>
</func>
<func>
- <name>activity(AccessContext, Fun, Args, AccessMod) -> ResultOfFun | exit(Reason)</name>
+ <name since="">activity(AccessContext, Fun, Args, AccessMod) -> ResultOfFun | exit(Reason)</name>
<fsummary>Executes <c>Fun</c> in <c>AccessContext</c>.</fsummary>
<desc>
<marker id="activity_4"></marker>
@@ -403,7 +403,7 @@
</desc>
</func>
<func>
- <name>add_table_copy(Tab, Node, Type) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">add_table_copy(Tab, Node, Type) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Copies a table to a remote node.</fsummary>
<desc>
<marker id="add_table_copy"></marker>
@@ -420,7 +420,7 @@ mnesia:add_table_copy(person, Node, disc_copies)</code>
</desc>
</func>
<func>
- <name>add_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">add_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Creates an index for a table.</fsummary>
<desc>
<marker id="add_table_index"></marker>
@@ -441,7 +441,7 @@ mnesia:add_table_index(person, age)</code>
</desc>
</func>
<func>
- <name>all_keys(Tab) -> KeyList | transaction abort</name>
+ <name since="">all_keys(Tab) -> KeyList | transaction abort</name>
<fsummary>Returns all keys in a table.</fsummary>
<desc>
<marker id="all_keys"></marker>
@@ -453,7 +453,7 @@ mnesia:add_table_index(person, age)</code>
</desc>
</func>
<func>
- <name>async_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
+ <name since="">async_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
<fsummary>Calls the <c>Fun</c> in a context that is not protected by a transaction.</fsummary>
<desc>
<marker id="async_dirty"></marker>
@@ -493,7 +493,7 @@ mnesia:add_table_index(person, age)</code>
</desc>
</func>
<func>
- <name>backup(Opaque [, BackupMod]) -> ok | {error,Reason}</name>
+ <name since="">backup(Opaque [, BackupMod]) -> ok | {error,Reason}</name>
<fsummary>Backs up all tables in the database.</fsummary>
<desc>
<marker id="backup"></marker>
@@ -505,7 +505,7 @@ mnesia:add_table_index(person, age)</code>
</desc>
</func>
<func>
- <name>backup_checkpoint(Name, Opaque [, BackupMod]) -> ok | {error,Reason}</name>
+ <name since="">backup_checkpoint(Name, Opaque [, BackupMod]) -> ok | {error,Reason}</name>
<fsummary>Backs up all tables in a checkpoint.</fsummary>
<desc>
<marker id="backup_checkpoint"></marker>
@@ -520,7 +520,7 @@ mnesia:add_table_index(person, age)</code>
</desc>
</func>
<func>
- <name>change_config(Config, Value) -> {error, Reason} | {ok, ReturnValue}</name>
+ <name since="">change_config(Config, Value) -> {error, Reason} | {ok, ReturnValue}</name>
<fsummary>Changes a configuration parameter.</fsummary>
<desc>
<marker id="change_config"></marker>
@@ -554,7 +554,7 @@ mnesia:add_table_index(person, age)</code>
</desc>
</func>
<func>
- <name>change_table_access_mode(Tab, AccessMode) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">change_table_access_mode(Tab, AccessMode) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Changes the access mode for the table.</fsummary>
<desc>
<marker id="change_table_access_mode"></marker>
@@ -568,7 +568,7 @@ mnesia:add_table_index(person, age)</code>
</desc>
</func>
<func>
- <name>change_table_copy_type(Tab, Node, To) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">change_table_copy_type(Tab, Node, To) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Changes the storage type of a table.</fsummary>
<desc>
<marker id="change_table_copy_type"></marker>
@@ -585,7 +585,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
</desc>
</func>
<func>
- <name>change_table_load_order(Tab, LoadOrder) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">change_table_load_order(Tab, LoadOrder) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Changes the load order priority for the table.</fsummary>
<desc>
<marker id="change_table_load_order"></marker>
@@ -595,7 +595,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
</desc>
</func>
<func>
- <name>change_table_majority(Tab, Majority) -> {aborted, R} | {atomic, ok}</name>
+ <name since="OTP R14B03">change_table_majority(Tab, Majority) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Changes the majority check setting for the table.</fsummary>
<desc>
<p><c>Majority</c> must be a boolean. Default is <c>false</c>.
@@ -607,7 +607,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
</desc>
</func>
<func>
- <name>clear_table(Tab) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">clear_table(Tab) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Deletes all entries in a table.</fsummary>
<desc>
<marker id="clear_table"></marker>
@@ -615,7 +615,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
</desc>
</func>
<func>
- <name>create_schema(DiscNodes) -> ok | {error,Reason}</name>
+ <name since="">create_schema(DiscNodes) -> ok | {error,Reason}</name>
<fsummary>Creates a new schema on the specified nodes.</fsummary>
<desc>
<marker id="create_schema"></marker>
@@ -637,7 +637,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
</desc>
</func>
<func>
- <name>create_table(Name, TabDef) -> {atomic, ok} | {aborted, Reason}</name>
+ <name since="">create_table(Name, TabDef) -> {atomic, ok} | {aborted, Reason}</name>
<fsummary>Creates a Mnesia table called <c>Name</c>with properties as described by argument <c>TabDef</c>.</fsummary>
<desc>
<marker id="create_table"></marker>
@@ -799,7 +799,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>deactivate_checkpoint(Name) -> ok | {error, Reason}</name>
+ <name since="">deactivate_checkpoint(Name) -> ok | {error, Reason}</name>
<fsummary>Deactivates a checkpoint.</fsummary>
<desc>
<marker id="deactivate_checkpoint"></marker>
@@ -811,7 +811,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>del_table_copy(Tab, Node) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">del_table_copy(Tab, Node) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Deletes the replica of table <c>Tab</c> at node <c>Node</c>.</fsummary>
<desc>
<marker id="del_table_copy"></marker>
@@ -825,7 +825,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>del_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">del_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Deletes an index in a table.</fsummary>
<desc>
<marker id="del_table_index"></marker>
@@ -834,7 +834,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>delete({Tab, Key}) -> transaction abort | ok</name>
+ <name since="">delete({Tab, Key}) -> transaction abort | ok</name>
<fsummary>Deletes all records in table <c>Tab</c> with the key <c>Key</c>.</fsummary>
<desc>
<marker id="delete_2"></marker>
@@ -842,7 +842,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>delete(Tab, Key, LockKind) -> transaction abort | ok</name>
+ <name since="">delete(Tab, Key, LockKind) -> transaction abort | ok</name>
<fsummary>Deletes all records in table <c>Tab</c>with the key <c>Key</c>.</fsummary>
<desc>
<marker id="delete_3"></marker>
@@ -857,7 +857,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>delete_object(Record) -> transaction abort | ok</name>
+ <name since="">delete_object(Record) -> transaction abort | ok</name>
<fsummary>Delete a record.</fsummary>
<desc>
<marker id="delete_object_1"></marker>
@@ -866,7 +866,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>delete_object(Tab, Record, LockKind) -> transaction abort | ok</name>
+ <name since="">delete_object(Tab, Record, LockKind) -> transaction abort | ok</name>
<fsummary>Deletes a record.</fsummary>
<desc>
<marker id="delete_object_3"></marker>
@@ -883,7 +883,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>delete_schema(DiscNodes) -> ok | {error,Reason}</name>
+ <name since="">delete_schema(DiscNodes) -> ok | {error,Reason}</name>
<fsummary>Deletes the schema on the given nodes.</fsummary>
<desc>
<marker id="delete_schema"></marker>
@@ -904,7 +904,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>delete_table(Tab) -> {aborted, Reason} | {atomic, ok}</name>
+ <name since="">delete_table(Tab) -> {aborted, Reason} | {atomic, ok}</name>
<fsummary>Deletes permanently all replicas of table <c>Tab</c>.</fsummary>
<desc>
<marker id="delete_table"></marker>
@@ -912,7 +912,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_all_keys(Tab) -> KeyList | exit({aborted, Reason})</name>
+ <name since="">dirty_all_keys(Tab) -> KeyList | exit({aborted, Reason})</name>
<fsummary>Dirty search for all record keys in table.</fsummary>
<desc>
<marker id="delete_all_keys"></marker>
@@ -920,7 +920,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_delete({Tab, Key}) -> ok | exit({aborted, Reason})</name>
+ <name since="">dirty_delete({Tab, Key}) -> ok | exit({aborted, Reason})</name>
<fsummary>Dirty delete of a record.</fsummary>
<desc>
<marker id="dirty_delete"></marker>
@@ -928,14 +928,14 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_delete(Tab, Key) -> ok | exit({aborted, Reason})</name>
+ <name since="">dirty_delete(Tab, Key) -> ok | exit({aborted, Reason})</name>
<fsummary>Dirty delete of a record.</fsummary>
<desc>
<p>Dirty equivalent of the function <c>mnesia:delete/3</c>.</p>
</desc>
</func>
<func>
- <name>dirty_delete_object(Record)</name>
+ <name since="">dirty_delete_object(Record)</name>
<fsummary>Dirty delete of a record.</fsummary>
<desc>
<marker id="dirty_delete_object_1"></marker>
@@ -944,14 +944,14 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_delete_object(Tab, Record)</name>
+ <name since="">dirty_delete_object(Tab, Record)</name>
<fsummary>Dirty delete of a record.</fsummary>
<desc>
<p>Dirty equivalent of the function <c>mnesia:delete_object/3</c>.</p>
</desc>
</func>
<func>
- <name>dirty_first(Tab) -> Key | exit({aborted, Reason})</name>
+ <name since="">dirty_first(Tab) -> Key | exit({aborted, Reason})</name>
<fsummary>Returns the key for the first record in a table.</fsummary>
<desc>
<marker id="dirty_first"></marker>
@@ -967,7 +967,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_index_match_object(Pattern, Pos)</name>
+ <name since="">dirty_index_match_object(Pattern, Pos)</name>
<fsummary>Dirty pattern match using index.</fsummary>
<desc>
<marker id="dirty_index_match_object_2"></marker>
@@ -977,7 +977,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_index_match_object(Tab, Pattern, Pos)</name>
+ <name since="">dirty_index_match_object(Tab, Pattern, Pos)</name>
<fsummary>Dirty pattern match using index.</fsummary>
<desc>
<p>Dirty equivalent of the function
@@ -985,7 +985,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_index_read(Tab, SecondaryKey, Pos)</name>
+ <name since="">dirty_index_read(Tab, SecondaryKey, Pos)</name>
<fsummary>Dirty read using index.</fsummary>
<desc>
<marker id="dirty_index_read"></marker>
@@ -994,7 +994,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_last(Tab) -> Key | exit({aborted, Reason})</name>
+ <name since="">dirty_last(Tab) -> Key | exit({aborted, Reason})</name>
<fsummary>Returns the key for the last record in a table.</fsummary>
<desc>
<marker id="dirty_last"></marker>
@@ -1006,7 +1006,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_match_object(Pattern) -> RecordList | exit({aborted, Reason})</name>
+ <name since="">dirty_match_object(Pattern) -> RecordList | exit({aborted, Reason})</name>
<fsummary>Dirty pattern match pattern.</fsummary>
<desc>
<marker id="dirty_match_object_1"></marker>
@@ -1015,7 +1015,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_match_object(Tab, Pattern) -> RecordList | exit({aborted, Reason})</name>
+ <name since="">dirty_match_object(Tab, Pattern) -> RecordList | exit({aborted, Reason})</name>
<fsummary>Dirty pattern match pattern.</fsummary>
<desc>
<p>Dirty equivalent of the function
@@ -1023,7 +1023,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_next(Tab, Key) -> Key | exit({aborted, Reason})</name>
+ <name since="">dirty_next(Tab, Key) -> Key | exit({aborted, Reason})</name>
<fsummary>Return the next key in a table.</fsummary>
<desc>
<marker id="dirty_next"></marker>
@@ -1038,7 +1038,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_prev(Tab, Key) -> Key | exit({aborted, Reason})</name>
+ <name since="">dirty_prev(Tab, Key) -> Key | exit({aborted, Reason})</name>
<fsummary>Returns the previous key in a table.</fsummary>
<desc>
<marker id="dirty_prev"></marker>
@@ -1050,7 +1050,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_read({Tab, Key}) -> ValueList | exit({aborted, Reason}</name>
+ <name since="">dirty_read({Tab, Key}) -> ValueList | exit({aborted, Reason}</name>
<fsummary>Dirty read of records.</fsummary>
<desc>
<marker id="dirty_read"></marker>
@@ -1058,14 +1058,14 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_read(Tab, Key) -> ValueList | exit({aborted, Reason}</name>
+ <name since="">dirty_read(Tab, Key) -> ValueList | exit({aborted, Reason}</name>
<fsummary>Dirty read of records.</fsummary>
<desc>
<p>Dirty equivalent of the function <c>mnesia:read/3</c>.</p>
</desc>
</func>
<func>
- <name>dirty_select(Tab, MatchSpec) -> ValueList | exit({aborted, Reason}</name>
+ <name since="">dirty_select(Tab, MatchSpec) -> ValueList | exit({aborted, Reason}</name>
<fsummary>Dirty matches the objects in <c>Tab</c> against <c>MatchSpec</c>.</fsummary>
<desc>
<marker id="dirty_select"></marker>
@@ -1073,7 +1073,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_slot(Tab, Slot) -> RecordList | exit({aborted, Reason})</name>
+ <name since="">dirty_slot(Tab, Slot) -> RecordList | exit({aborted, Reason})</name>
<fsummary>Returns the list of records that are associated with <c>Slot</c> in a table.</fsummary>
<desc>
<marker id="dirty_slot"></marker>
@@ -1089,7 +1089,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_update_counter({Tab, Key}, Incr) -> NewVal | exit({aborted, Reason})</name>
+ <name since="">dirty_update_counter({Tab, Key}, Incr) -> NewVal | exit({aborted, Reason})</name>
<fsummary>Dirty update of a counter record.</fsummary>
<desc>
<marker id="dirty_update_counter"></marker>
@@ -1097,7 +1097,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_update_counter(Tab, Key, Incr) -> NewVal | exit({aborted, Reason})</name>
+ <name since="">dirty_update_counter(Tab, Key, Incr) -> NewVal | exit({aborted, Reason})</name>
<fsummary>Dirty update of a counter record.</fsummary>
<desc>
<p>Mnesia has no special counter records. However,
@@ -1126,7 +1126,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_write(Record) -> ok | exit({aborted, Reason})</name>
+ <name since="">dirty_write(Record) -> ok | exit({aborted, Reason})</name>
<fsummary>Dirty write of a record.</fsummary>
<desc>
<marker id="dirty_write_1"></marker>
@@ -1135,14 +1135,14 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dirty_write(Tab, Record) -> ok | exit({aborted, Reason})</name>
+ <name since="">dirty_write(Tab, Record) -> ok | exit({aborted, Reason})</name>
<fsummary>Dirty write of a record.</fsummary>
<desc>
<p>Dirty equivalent of the function <c>mnesia:write/3</c>.</p>
</desc>
</func>
<func>
- <name>dump_log() -> dumped</name>
+ <name since="">dump_log() -> dumped</name>
<fsummary>Performs a user-initiated dump of the local log file.</fsummary>
<desc>
<marker id="dump_log"></marker>
@@ -1156,7 +1156,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dump_tables(TabList) -> {atomic, ok} | {aborted, Reason}</name>
+ <name since="">dump_tables(TabList) -> {atomic, ok} | {aborted, Reason}</name>
<fsummary>Dumps all RAM tables to disc.</fsummary>
<desc>
<marker id="dump_tables"></marker>
@@ -1168,7 +1168,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>dump_to_textfile(Filename)</name>
+ <name since="">dump_to_textfile(Filename)</name>
<fsummary>Dumps local tables into a text file.</fsummary>
<desc>
<marker id="dump_to_textfile"></marker>
@@ -1181,7 +1181,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>error_description(Error) -> String</name>
+ <name since="">error_description(Error) -> String</name>
<fsummary>Returns a string describing a particular Mnesia error.</fsummary>
<desc>
<marker id="error_description"></marker>
@@ -1259,7 +1259,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>ets(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
+ <name since="">ets(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
<fsummary>Calls the <c>Fun</c> in a raw context that is not protected by a transaction.</fsummary>
<desc>
<marker id="ets"></marker>
@@ -1278,7 +1278,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>first(Tab) -> Key | transaction abort</name>
+ <name since="">first(Tab) -> Key | transaction abort</name>
<fsummary>Returns the key for the first record in a table.</fsummary>
<desc>
<marker id="first"></marker>
@@ -1293,7 +1293,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>foldl(Function, Acc, Table) -> NewAcc | transaction abort</name>
+ <name since="">foldl(Function, Acc, Table) -> NewAcc | transaction abort</name>
<fsummary>Calls <c>Function</c> for each record in <c>Table</c>.</fsummary>
<desc>
<marker id="foldl"></marker>
@@ -1306,7 +1306,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>foldr(Function, Acc, Table) -> NewAcc | transaction abort</name>
+ <name since="">foldr(Function, Acc, Table) -> NewAcc | transaction abort</name>
<fsummary>Calls <c>Function</c> for each record in <c>Table</c>.</fsummary>
<desc>
<marker id="foldr"></marker>
@@ -1317,7 +1317,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>force_load_table(Tab) -> yes | ErrorDescription</name>
+ <name since="">force_load_table(Tab) -> yes | ErrorDescription</name>
<fsummary>Forces a table to be loaded into the system.</fsummary>
<desc>
<marker id="force_load_table"></marker>
@@ -1335,7 +1335,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>index_match_object(Pattern, Pos) -> transaction abort | ObjList</name>
+ <name since="">index_match_object(Pattern, Pos) -> transaction abort | ObjList</name>
<fsummary>Matches records and uses index information.</fsummary>
<desc>
<marker id="index_match_object_2"></marker>
@@ -1345,7 +1345,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>index_match_object(Tab, Pattern, Pos, LockKind) -> transaction abort | ObjList</name>
+ <name since="">index_match_object(Tab, Pattern, Pos, LockKind) -> transaction abort | ObjList</name>
<fsummary>Matches records and uses index information.</fsummary>
<desc>
<marker id="index_match_object_4"></marker>
@@ -1377,7 +1377,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>index_read(Tab, SecondaryKey, Pos) -> transaction abort | RecordList</name>
+ <name since="">index_read(Tab, SecondaryKey, Pos) -> transaction abort | RecordList</name>
<fsummary>Reads records through index table.</fsummary>
<desc>
<marker id="index_read"></marker>
@@ -1397,7 +1397,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>info() -> ok</name>
+ <name since="">info() -> ok</name>
<fsummary>Prints system information on the terminal.</fsummary>
<desc>
<marker id="info"></marker>
@@ -1408,7 +1408,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>install_fallback(Opaque) -> ok | {error,Reason}</name>
+ <name since="">install_fallback(Opaque) -> ok | {error,Reason}</name>
<fsummary>Installs a backup as fallback.</fsummary>
<desc>
<marker id="install_fallback_1"></marker>
@@ -1417,7 +1417,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>install_fallback(Opaque), BackupMod) -> ok | {error,Reason}</name>
+ <name since="">install_fallback(Opaque), BackupMod) -> ok | {error,Reason}</name>
<fsummary>Installs a backup as fallback.</fsummary>
<desc>
<p>Calls <c>mnesia:install_fallback(Opaque, Args)</c>, where
@@ -1425,7 +1425,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>install_fallback(Opaque, Args) -> ok | {error,Reason}</name>
+ <name since="">install_fallback(Opaque, Args) -> ok | {error,Reason}</name>
<fsummary>Installs a backup as fallback.</fsummary>
<desc>
<p>Installs a backup as fallback. The fallback is used to
@@ -1483,7 +1483,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>is_transaction() -> boolean</name>
+ <name since="">is_transaction() -> boolean</name>
<fsummary>Checks if code is running in a transaction.</fsummary>
<desc>
<marker id="is_transaction"></marker>
@@ -1492,7 +1492,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>last(Tab) -> Key | transaction abort</name>
+ <name since="">last(Tab) -> Key | transaction abort</name>
<fsummary>Returns the key for the last record in a table.</fsummary>
<desc>
<p>Works exactly like
@@ -1503,7 +1503,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>load_textfile(Filename)</name>
+ <name since="">load_textfile(Filename)</name>
<fsummary>Loads tables from a text file.</fsummary>
<desc>
<marker id="load_textfile"></marker>
@@ -1516,7 +1516,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>lock(LockItem, LockKind) -> Nodes | ok | transaction abort</name>
+ <name since="">lock(LockItem, LockKind) -> Nodes | ok | transaction abort</name>
<fsummary>Explicit grab lock.</fsummary>
<desc>
<marker id="lock"></marker>
@@ -1605,7 +1605,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>match_object(Pattern) -> transaction abort | RecList</name>
+ <name since="">match_object(Pattern) -> transaction abort | RecList</name>
<fsummary>Matches <c>Pattern</c> for records.</fsummary>
<desc>
<marker id="match_object_1"></marker>
@@ -1614,7 +1614,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>match_object(Tab, Pattern, LockKind) -> transaction abort | RecList</name>
+ <name since="">match_object(Tab, Pattern, LockKind) -> transaction abort | RecList</name>
<fsummary>Matches <c>Pattern</c> for records.</fsummary>
<desc>
<marker id="match_object_3"></marker>
@@ -1639,7 +1639,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>move_table_copy(Tab, From, To) -> {aborted, Reason} | {atomic, ok}</name>
+ <name since="">move_table_copy(Tab, From, To) -> {aborted, Reason} | {atomic, ok}</name>
<fsummary>Moves the copy of table <c>Tab</c> from node <c>From</c> to node <c>To</c>.</fsummary>
<desc>
<marker id="move_table_copy"></marker>
@@ -1653,7 +1653,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>next(Tab, Key) -> Key | transaction abort</name>
+ <name since="">next(Tab, Key) -> Key | transaction abort</name>
<fsummary>Returns the next key in a table.</fsummary>
<desc>
<marker id="next"></marker>
@@ -1665,7 +1665,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>prev(Tab, Key) -> Key | transaction abort</name>
+ <name since="">prev(Tab, Key) -> Key | transaction abort</name>
<fsummary>Returns the previous key in a table.</fsummary>
<desc>
<p>Works exactly like
@@ -1676,7 +1676,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>read({Tab, Key}) -> transaction abort | RecordList</name>
+ <name since="">read({Tab, Key}) -> transaction abort | RecordList</name>
<fsummary>Reads records(s) with a given key.</fsummary>
<desc>
<marker id="read_2"></marker>
@@ -1684,14 +1684,14 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>read(Tab, Key) -> transaction abort | RecordList</name>
+ <name since="">read(Tab, Key) -> transaction abort | RecordList</name>
<fsummary>Reads records(s) with a given key.</fsummary>
<desc>
<p>Calls function <c>mnesia:read(Tab, Key, read)</c>.</p>
</desc>
</func>
<func>
- <name>read(Tab, Key, LockKind) -> transaction abort | RecordList</name>
+ <name since="">read(Tab, Key, LockKind) -> transaction abort | RecordList</name>
<fsummary>Reads records(s) with a given key.</fsummary>
<desc>
<marker id="read_3"></marker>
@@ -1716,7 +1716,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>read_lock_table(Tab) -> ok | transaction abort</name>
+ <name since="">read_lock_table(Tab) -> ok | transaction abort</name>
<fsummary>Sets a read lock on an entire table.</fsummary>
<desc>
<marker id="read_lock_table"></marker>
@@ -1725,7 +1725,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>report_event(Event) -> ok</name>
+ <name since="">report_event(Event) -> ok</name>
<fsummary>Reports a user event to the Mnesia event handler.</fsummary>
<desc>
<marker id="report_event"></marker>
@@ -1743,7 +1743,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>restore(Opaque, Args) -> {atomic, RestoredTabs} |{aborted, Reason}</name>
+ <name since="">restore(Opaque, Args) -> {atomic, RestoredTabs} |{aborted, Reason}</name>
<fsummary>Online restore of backup.</fsummary>
<desc>
<marker id="restore"></marker>
@@ -1803,7 +1803,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>s_delete({Tab, Key}) -> ok | transaction abort</name>
+ <name since="">s_delete({Tab, Key}) -> ok | transaction abort</name>
<fsummary>Sets sticky lock and delete records.</fsummary>
<desc>
<marker id="s_delete"></marker>
@@ -1812,7 +1812,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>s_delete_object(Record) -> ok | transaction abort</name>
+ <name since="">s_delete_object(Record) -> ok | transaction abort</name>
<fsummary>Sets sticky lock and delete record.</fsummary>
<desc>
<marker id="s_delete_object"></marker>
@@ -1822,7 +1822,7 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>s_write(Record) -> ok | transaction abort</name>
+ <name since="">s_write(Record) -> ok | transaction abort</name>
<fsummary>Writes <c>Record</c> and sets sticky lock.</fsummary>
<desc>
<marker id="s_write"></marker>
@@ -1832,21 +1832,21 @@ mnesia:create_table(person,
</desc>
</func>
<func>
- <name>schema() -> ok</name>
+ <name since="">schema() -> ok</name>
<fsummary>Prints information about all table definitions on the terminal.</fsummary>
<desc>
<p>Prints information about all table definitions on the terminal.</p>
</desc>
</func>
<func>
- <name>schema(Tab) -> ok</name>
+ <name since="">schema(Tab) -> ok</name>
<fsummary>Prints information about one table definition on the terminal.</fsummary>
<desc>
<p>Prints information about one table definition on the terminal.</p>
</desc>
</func>
<func>
- <name>select(Tab, MatchSpec [, Lock]) -> transaction abort | [Object]</name>
+ <name since="">select(Tab, MatchSpec [, Lock]) -> transaction abort | [Object]</name>
<fsummary>Matches the objects in <c>Tab</c> against <c>MatchSpec</c>.</fsummary>
<desc>
<marker id="select_2_3"></marker>
@@ -1884,7 +1884,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>select(Tab, MatchSpec, NObjects, Lock) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
+ <name since="">select(Tab, MatchSpec, NObjects, Lock) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
<fsummary>Matches the objects in <c>Tab</c> against <c>MatchSpec</c>.</fsummary>
<desc>
<marker id="select_4"></marker>
@@ -1907,7 +1907,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>select(Cont) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
+ <name since="">select(Cont) -> transaction abort | {[Object],Cont} | '$end_of_table'</name>
<fsummary>Continues selecting objects.</fsummary>
<desc>
<p>Selects more objects with the match specification initiated
@@ -1919,7 +1919,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>set_debug_level(Level) -> OldLevel</name>
+ <name since="">set_debug_level(Level) -> OldLevel</name>
<fsummary>Changes the internal debug level of Mnesia.</fsummary>
<desc>
<marker id="set_debug_level"></marker>
@@ -1930,7 +1930,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>set_master_nodes(MasterNodes) -> ok | {error, Reason}</name>
+ <name since="">set_master_nodes(MasterNodes) -> ok | {error, Reason}</name>
<fsummary>Sets the master nodes for all tables.</fsummary>
<desc>
<marker id="set_master_nodes_1"></marker>
@@ -1943,7 +1943,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>set_master_nodes(Tab, MasterNodes) -> ok | {error, Reason}</name>
+ <name since="">set_master_nodes(Tab, MasterNodes) -> ok | {error, Reason}</name>
<fsummary>Sets the master nodes for a table.</fsummary>
<desc>
<marker id="set_master_nodes_2"></marker>
@@ -1968,14 +1968,14 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>snmp_close_table(Tab) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">snmp_close_table(Tab) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Removes the possibility for SNMP to manipulate the table.</fsummary>
<desc>
<p>Removes the possibility for SNMP to manipulate the table.</p>
</desc>
</func>
<func>
- <name>snmp_get_mnesia_key(Tab, RowIndex) -> {ok, Key} | undefined</name>
+ <name since="">snmp_get_mnesia_key(Tab, RowIndex) -> {ok, Key} | undefined</name>
<fsummary>Gets the corresponding Mnesia key from an SNMP index.</fsummary>
<type>
<v>Tab ::= atom()</v>
@@ -1990,7 +1990,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>snmp_get_next_index(Tab, RowIndex) -> {ok, NextIndex} | endOfTable</name>
+ <name since="">snmp_get_next_index(Tab, RowIndex) -> {ok, NextIndex} | endOfTable</name>
<fsummary>Gets the index of the next lexicographical row.</fsummary>
<type>
<v>Tab ::= atom()</v>
@@ -2006,7 +2006,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>snmp_get_row(Tab, RowIndex) -> {ok, Row} | undefined</name>
+ <name since="">snmp_get_row(Tab, RowIndex) -> {ok, Row} | undefined</name>
<fsummary>Retrieves a row indexed by an SNMP index.</fsummary>
<type>
<v>Tab ::= atom()</v>
@@ -2019,7 +2019,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</desc>
</func>
<func>
- <name>snmp_open_table(Tab, SnmpStruct) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">snmp_open_table(Tab, SnmpStruct) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Organizes a Mnesia table as an SNMP table.</fsummary>
<type>
<v>Tab ::= atom()</v>
@@ -2073,10 +2073,17 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>start() -> ok | {error, Reason}</name>
+ <name since="">start() -> ok | {error, Reason}</name>
<fsummary>Starts a local Mnesia system.</fsummary>
<desc>
<marker id="start"></marker>
+ <p>Mnesia startup is asynchronous. The function call
+ <c>mnesia:start()</c> returns the atom <c>ok</c> and then
+ starts to initialize the different tables. Depending on the
+ size of the database, this can take some time, and the
+ application programmer must wait for the tables that the
+ application needs before they can be used. This is achieved
+ by using the function <c>mnesia:wait_for_tables/2</c>.</p>
<p>The startup procedure for a set of Mnesia nodes is a
fairly complicated operation. A Mnesia system consists
of a set of nodes, with Mnesia started locally on all
@@ -2108,7 +2115,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>stop() -> stopped</name>
+ <name since="">stop() -> stopped</name>
<fsummary>Stops Mnesia locally.</fsummary>
<desc>
<marker id="stop"></marker>
@@ -2117,7 +2124,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>subscribe(EventCategory) -> {ok, Node} | {error, Reason}</name>
+ <name since="">subscribe(EventCategory) -> {ok, Node} | {error, Reason}</name>
<fsummary>Subscribes to events of type <c>EventCategory</c>.</fsummary>
<desc>
<marker id="subscribe"></marker>
@@ -2127,7 +2134,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>sync_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
+ <name since="">sync_dirty(Fun, [, Args]) -> ResultOfFun | exit(Reason)</name>
<fsummary>Calls the <c>Fun</c> in a context that is not protected by a transaction.</fsummary>
<desc>
<marker id="sync_dirty"></marker>
@@ -2143,7 +2150,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>sync_log() -> ok | {error, Reason}</name>
+ <name since="OTP 17.0">sync_log() -> ok | {error, Reason}</name>
<fsummary>Performs a file sync of the local log file.</fsummary>
<desc>
<p>Ensures that the local transaction log file is synced to disk.
@@ -2153,7 +2160,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>sync_transaction(Fun, [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun}</name>
+ <name since="">sync_transaction(Fun, [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun}</name>
<fsummary>Synchronously executes a transaction.</fsummary>
<desc>
<marker id="sync_transaction"></marker>
@@ -2166,7 +2173,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>system_info(InfoKey) -> Info | exit({aborted, Reason})</name>
+ <name since="">system_info(InfoKey) -> Info | exit({aborted, Reason})</name>
<fsummary>Returns information about the Mnesia system.</fsummary>
<desc>
<marker id="system_info"></marker>
@@ -2353,7 +2360,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>table(Tab [,[Option]]) -> QueryHandle</name>
+ <name since="">table(Tab [,[Option]]) -> QueryHandle</name>
<fsummary>Return a QLC query handle.</fsummary>
<desc>
<marker id="table"></marker>
@@ -2408,7 +2415,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>table_info(Tab, InfoKey) -> Info | exit({aborted, Reason})</name>
+ <name since="">table_info(Tab, InfoKey) -> Info | exit({aborted, Reason})</name>
<fsummary>Returns local information about table.</fsummary>
<desc>
<marker id="table_info"></marker>
@@ -2560,7 +2567,7 @@ mnesia:create_table(employee,
</desc>
</func>
<func>
- <name>transaction(Fun [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun}</name>
+ <name since="">transaction(Fun [[, Args], Retries]) -> {aborted, Reason} | {atomic, ResultOfFun}</name>
<fsummary>Executes a transaction.</fsummary>
<desc>
<marker id="transaction"></marker>
@@ -2628,7 +2635,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>transform_table(Tab, Fun, NewAttributeList, NewRecordName) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">transform_table(Tab, Fun, NewAttributeList, NewRecordName) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Changes format on all records in table <c>Tab</c>.</fsummary>
<desc>
<marker id="transform_table_4"></marker>
@@ -2649,7 +2656,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>transform_table(Tab, Fun, NewAttributeList) -> {aborted, R} | {atomic, ok}</name>
+ <name since="">transform_table(Tab, Fun, NewAttributeList) -> {aborted, R} | {atomic, ok}</name>
<fsummary>Changes format on all records in table <c>Tab</c>.</fsummary>
<desc>
<p>Calls <c>mnesia:transform_table(Tab, Fun,
@@ -2658,7 +2665,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>traverse_backup(Source, [SourceMod,] Target, [TargetMod,] Fun, Acc) -> {ok, LastAcc} | {error, Reason}</name>
+ <name since="">traverse_backup(Source, [SourceMod,] Target, [TargetMod,] Fun, Acc) -> {ok, LastAcc} | {error, Reason}</name>
<fsummary>Traversal of a backup.</fsummary>
<desc>
<marker id="traverse_backup"></marker>
@@ -2689,7 +2696,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>uninstall_fallback() -> ok | {error,Reason}</name>
+ <name since="">uninstall_fallback() -> ok | {error,Reason}</name>
<fsummary>Uninstalls a fallback.</fsummary>
<desc>
<marker id="uninstall_fallback_0"></marker>
@@ -2698,7 +2705,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>uninstall_fallback(Args) -> ok | {error,Reason}</name>
+ <name since="">uninstall_fallback(Args) -> ok | {error,Reason}</name>
<fsummary>Uninstalls a fallback.</fsummary>
<desc>
<p>Deinstalls a fallback before it
@@ -2725,7 +2732,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>unsubscribe(EventCategory) -> {ok, Node} | {error, Reason}</name>
+ <name since="">unsubscribe(EventCategory) -> {ok, Node} | {error, Reason}</name>
<fsummary>Subscribes to events of type <c>EventCategory</c>.</fsummary>
<desc>
<marker id="unsubscribe"></marker>
@@ -2735,7 +2742,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>wait_for_tables(TabList, Timeout) -> ok | {timeout, BadTabList} | {error, Reason}</name>
+ <name since="">wait_for_tables(TabList, Timeout) -> ok | {timeout, BadTabList} | {error, Reason}</name>
<fsummary>Waits for tables to be accessible.</fsummary>
<desc>
<marker id="wait_for_tables"></marker>
@@ -2746,7 +2753,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>wread({Tab, Key}) -> transaction abort | RecordList</name>
+ <name since="">wread({Tab, Key}) -> transaction abort | RecordList</name>
<fsummary>Reads records with given key.</fsummary>
<desc>
<marker id="wread"></marker>
@@ -2754,7 +2761,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>write(Record) -> transaction abort | ok</name>
+ <name since="">write(Record) -> transaction abort | ok</name>
<fsummary>Writes a record into the database.</fsummary>
<desc>
<marker id="write_1"></marker>
@@ -2763,7 +2770,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>write(Tab, Record, LockKind) -> transaction abort | ok</name>
+ <name since="">write(Tab, Record, LockKind) -> transaction abort | ok</name>
<fsummary>Writes a record into the database.</fsummary>
<desc>
<marker id="write_3"></marker>
@@ -2779,7 +2786,7 @@ raise(Name, Amount) ->
</desc>
</func>
<func>
- <name>write_lock_table(Tab) -> ok | transaction abort</name>
+ <name since="">write_lock_table(Tab) -> ok | transaction abort</name>
<fsummary>Sets write lock on an entire table.</fsummary>
<desc>
<marker id="write_lock_table"></marker>
diff --git a/lib/mnesia/doc/src/mnesia_frag_hash.xml b/lib/mnesia/doc/src/mnesia_frag_hash.xml
index 51b32129b6..ccaba412d0 100644
--- a/lib/mnesia/doc/src/mnesia_frag_hash.xml
+++ b/lib/mnesia/doc/src/mnesia_frag_hash.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2002</year>
- <year>2016</year>
+ <year>2018</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -34,7 +34,7 @@
<rev>A</rev>
<file>mnesia_frag_hash.sgml</file>
</header>
- <module>mnesia_frag_hash</module>
+ <module since="">mnesia_frag_hash</module>
<modulesummary>Defines mnesia_frag_hash callback behavior</modulesummary>
<description>
<p>This module defines a callback behavior for user-defined hash
@@ -50,7 +50,7 @@
<funcs>
<func>
- <name>init_state(Tab, State) -> NewState | abort(Reason)</name>
+ <name since="">init_state(Tab, State) -> NewState | abort(Reason)</name>
<fsummary>Initiates the hash state for a new table.</fsummary>
<type>
<v>Tab = atom()</v>
@@ -72,7 +72,7 @@
</desc>
</func>
<func>
- <name>add_frag(State) -> {NewState, IterFrags, AdditionalLockFrags} | abort(Reason)</name>
+ <name since="">add_frag(State) -> {NewState, IterFrags, AdditionalLockFrags} | abort(Reason)</name>
<fsummary>Starts when a new fragment is added to a fragmented table.</fsummary>
<type>
<v>State = term()</v>
@@ -100,7 +100,7 @@
</desc>
</func>
<func>
- <name>del_frag(State) -> {NewState, IterFrags, AdditionalLockFrags} | abort(Reason)</name>
+ <name since="">del_frag(State) -> {NewState, IterFrags, AdditionalLockFrags} | abort(Reason)</name>
<fsummary>Starts when a fragment is deleted from a fragmented table.</fsummary>
<type>
<v>State = term()</v>
@@ -127,10 +127,10 @@
</desc>
</func>
<func>
- <name>key_to_frag_number(State, Key) -> FragNum | abort(Reason)</name>
+ <name since="">key_to_frag_number(State, Key) -> FragNum | abort(Reason)</name>
<fsummary>Resolves the key of a record into a fragment number.</fsummary>
<type>
- <v>FragNum = integer()()</v>
+ <v>FragNum = integer()</v>
<v>Reason = term()</v>
</type>
<desc>
@@ -140,7 +140,7 @@
</desc>
</func>
<func>
- <name>match_spec_to_frag_numbers(State, MatchSpec) -> FragNums | abort(Reason)</name>
+ <name since="">match_spec_to_frag_numbers(State, MatchSpec) -> FragNums | abort(Reason)</name>
<fsummary>Resolves a <c>MatchSpec</c> into a list of fragment numbers.</fsummary>
<type>
<v>MatcSpec = ets_select_match_spec()</v>
diff --git a/lib/mnesia/doc/src/mnesia_registry.xml b/lib/mnesia/doc/src/mnesia_registry.xml
index a76f716981..18ddc4ab9e 100644
--- a/lib/mnesia/doc/src/mnesia_registry.xml
+++ b/lib/mnesia/doc/src/mnesia_registry.xml
@@ -34,7 +34,7 @@
<rev>A</rev>
<file>mnesia_registry.sgml</file>
</header>
- <module>mnesia_registry</module>
+ <module since="">mnesia_registry</module>
<modulesummary>Dump support for registries in erl_interface.</modulesummary>
<description>
<p>This module is usually part of the <c>erl_interface</c>
@@ -57,7 +57,7 @@
<funcs>
<func>
- <name>create_table(Tab) -> ok | exit(Reason)</name>
+ <name since="">create_table(Tab) -> ok | exit(Reason)</name>
<fsummary>Creates a registry table in Mnesia.</fsummary>
<desc>
<p>A wrapper function for <c>mnesia:create_table/2</c>,
@@ -73,7 +73,7 @@
</desc>
</func>
<func>
- <name>create_table(Tab, TabDef) -> ok | exit(Reason)</name>
+ <name since="">create_table(Tab, TabDef) -> ok | exit(Reason)</name>
<fsummary>Creates a customized registry table in Mnesia.</fsummary>
<desc>
<p>A wrapper function for <c>mnesia:create_table/2</c>,
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index ba94e913f5..22fb5e8c48 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2017</year>
+ <year>1996</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -39,7 +39,111 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.15.3</title>
+ <section><title>Mnesia 4.15.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Avoid overload warnings caused by a race condition.</p>
+ <p>
+ Own Id: OTP-15619 Aux Id: ERIERL-310 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.15.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed type spec for <c>mnesia:change_config/2</c>.</p>
+ <p>
+ Own Id: OTP-15201 Aux Id: PR-1881 </p>
+ </item>
+ <item>
+ <p>
+ When master node is set do not force a load from
+ ram_copies replica when there are no available
+ disc_copies, since that would load an empty table. Wait
+ until a disk replica is available or until user
+ explicitly force_loads the table.</p>
+ <p>
+ Own Id: OTP-15221 Aux Id: ERIERL-217 </p>
+ </item>
+ <item>
+ <p>
+ Allow to add replicas even if all other replicas are down
+ when the other replicas are not stored on disk.</p>
+ <p>
+ Own Id: OTP-15226 Aux Id: ERIERL-221 </p>
+ </item>
+ <item>
+ <p>
+ Fixed <c>mnesia:delete_object/1</c> bug, where
+ delete_object was deleting the record if it was written
+ in the same transaction even if it was written to a
+ different value.</p>
+ <p>
+ Own Id: OTP-15231 Aux Id: PR-1858 </p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug where the bag table index data was not
+ deleted when objects were deleted.</p>
+ <p>
+ Own Id: OTP-15243</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.15.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Calls to <c>erlang:get_stacktrace()</c> are removed.
+ </p>
+ <p>
+ Own Id: OTP-14861</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.15.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When master node is set do not force a load from
+ ram_copies replica when there are no available
+ disc_copies, since that would load an empty table. Wait
+ until a disk replica is available or until user
+ explicitly force_loads the table.</p>
+ <p>
+ Own Id: OTP-15221 Aux Id: ERIERL-217 </p>
+ </item>
+ <item>
+ <p>
+ Allow to add replicas even if all other replicas are down
+ when the other replicase are not stored on disk.</p>
+ <p>
+ Own Id: OTP-15226 Aux Id: ERIERL-221 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.15.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 1842769778..223dba3f90 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -168,6 +168,9 @@
-type snmp_struct() :: [{atom(), snmp_type() | tuple_of(snmp_type())}].
-type snmp_type() :: 'fix_string' | 'string' | 'integer'.
-type tuple_of(_T) :: tuple().
+-type config_key() :: extra_db_nodes | dc_dump_limit.
+-type config_value() :: [node()] | number().
+-type config_result() :: {ok, config_value()} | {error, term()}.
-define(DEFAULT_ACCESS, ?MODULE).
@@ -177,8 +180,8 @@
%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
Value -> Value
end.
@@ -278,7 +281,8 @@ stop() ->
Other -> Other
end.
--spec change_config(Config::atom(), Value::_) -> ok | {error, term()}.
+-spec change_config(Config::config_key(), Value::config_value()) ->
+ config_result().
change_config(extra_db_nodes, Ns) when is_list(Ns) ->
mnesia_controller:connect_nodes(Ns);
change_config(dc_dump_limit, N) when is_number(N), N > 0 ->
@@ -779,12 +783,16 @@ do_delete_object(Tid, Ts, Tab, Val, LockKind) ->
?ets_insert(Store, {Oid, Val, delete_object});
_ ->
case ?ets_match_object(Store, {Oid, '_', write}) of
- [] ->
- ?ets_match_delete(Store, {Oid, Val, '_'}),
- ?ets_insert(Store, {Oid, Val, delete_object});
- _ ->
- ?ets_delete(Store, Oid),
- ?ets_insert(Store, {Oid, Oid, delete})
+ [] ->
+ ?ets_match_delete(Store, {Oid, Val, '_'}),
+ ?ets_insert(Store, {Oid, Val, delete_object});
+ Ops ->
+ case lists:member({Oid, Val, write}, Ops) of
+ true ->
+ ?ets_delete(Store, Oid),
+ ?ets_insert(Store, {Oid, Oid, delete});
+ false -> ok
+ end
end
end,
ok;
@@ -2682,7 +2690,7 @@ del_table_index(Tab, Ix) ->
-spec transform_table(Tab::table(), Fun, [Attr]) -> t_result(ok) when
Attr :: atom(),
- Fun:: fun((Record::tuple()) -> Transformed::tuple()).
+ Fun:: fun((Record::tuple()) -> Transformed::tuple()) | ignore.
transform_table(Tab, Fun, NewA) ->
try val({Tab, record_name}) of
OldRN -> mnesia_schema:transform_table(Tab, Fun, NewA, OldRN)
@@ -2693,7 +2701,7 @@ transform_table(Tab, Fun, NewA) ->
-spec transform_table(Tab::table(), Fun, [Attr], RecName) -> t_result(ok) when
RecName :: atom(),
Attr :: atom(),
- Fun:: fun((Record::tuple()) -> Transformed::tuple()).
+ Fun:: fun((Record::tuple()) -> Transformed::tuple()) | ignore.
transform_table(Tab, Fun, NewA, NewRN) ->
mnesia_schema:transform_table(Tab, Fun, NewA, NewRN).
diff --git a/lib/mnesia/src/mnesia.hrl b/lib/mnesia/src/mnesia.hrl
index da7e662288..fe48a6fe3d 100644
--- a/lib/mnesia/src/mnesia.hrl
+++ b/lib/mnesia/src/mnesia.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -47,6 +47,10 @@
-define(catch_val(Var), (try ?ets_lookup_element(mnesia_gvar, Var, 2)
catch error:_ -> {'EXIT', {badarg, []}} end)).
+-define(catch_val_and_stack(Var),
+ (try ?ets_lookup_element(mnesia_gvar, Var, 2)
+ catch error:_:_Stacktrace -> {'EXIT', _Stacktrace} end)).
+
%% It's important that counter is first, since we compare tid's
-record(tid,
diff --git a/lib/mnesia/src/mnesia_bup.erl b/lib/mnesia/src/mnesia_bup.erl
index 34f16f178b..e57fc5199d 100644
--- a/lib/mnesia/src/mnesia_bup.erl
+++ b/lib/mnesia/src/mnesia_bup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -90,9 +90,9 @@ iterate(Mod, Fun, Opaque, Acc) ->
catch throw:Err ->
close_read(R2),
Err;
- _:Reason ->
+ _:Reason:Stacktrace ->
close_read(R2),
- {error, {Reason, erlang:get_stacktrace()}}
+ {error, {Reason, Stacktrace}}
end
catch throw:{error,_} = Err ->
Err
@@ -198,9 +198,9 @@ do_read_schema_section(R) ->
try
{R3, RawSchema} = safe_apply(R2, read, [R2#restore.bup_data]),
do_read_schema_section(R3, verify_header(RawSchema), [])
- catch T:E ->
+ catch T:E:S ->
close_read(R2),
- erlang:raise(T,E,erlang:get_stacktrace())
+ erlang:raise(T,E,S)
end.
do_read_schema_section(R, {ok, B, C, []}, Acc) ->
diff --git a/lib/mnesia/src/mnesia_checkpoint.erl b/lib/mnesia/src/mnesia_checkpoint.erl
index 8112378ffd..3273d3d27e 100644
--- a/lib/mnesia/src/mnesia_checkpoint.erl
+++ b/lib/mnesia/src/mnesia_checkpoint.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017
+%% Copyright Ericsson AB 1996-2018
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1269,9 +1269,9 @@ system_code_change(Cp, _Module, _OldVsn, _Extra) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
- _VaLuE_ -> _VaLuE_
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
+ Value -> Value
end.
-
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 77013489b3..882de0d613 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -185,9 +185,10 @@ max_loaders() ->
worker_res
}).
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
Value -> Value
end.
@@ -771,22 +772,6 @@ handle_call({unannounce_add_table_copy, [Tab, Node], From}, ReplyTo, State) ->
noreply(State#state{early_msgs = [{call, Msg, undefined} | Msgs]})
end;
-handle_call({net_load, Tab, Cs}, From, State) ->
- State2 =
- case State#state.schema_is_merged of
- true ->
- Worker = #net_load{table = Tab,
- opt_reply_to = From,
- reason = {dumper,{add_table_copy, unknown}},
- cstruct = Cs
- },
- add_worker(Worker, State);
- false ->
- reply(From, {not_loaded, schema_not_merged}),
- State
- end,
- noreply(State2);
-
handle_call(Msg, From, State) when State#state.schema_is_merged /= true ->
%% Buffer early messages
Msgs = State#state.early_msgs,
@@ -1456,7 +1441,8 @@ orphan_tables([Tab | Tabs], Node, Ns, Local, Remote) ->
L = [Tab | Local],
orphan_tables(Tabs, Node, Ns, L, Remote);
Masters ->
- R = [{Tab, Masters} | Remote],
+ %% Do not disc_load table from RamCopyHolders
+ R = [{Tab, Masters -- RamCopyHolders} | Remote],
orphan_tables(Tabs, Node, Ns, Local, R)
end;
_ ->
@@ -2161,6 +2147,15 @@ load_table_fun(#net_load{cstruct=Cs, table=Tab, reason=Reason, opt_reply_to=Repl
{dumper,{add_table_copy,_}} -> true;
_ -> false
end,
+
+ OnlyRamCopies = case Cs of
+ #cstruct{disc_copies = DC,
+ disc_only_copies = DOC,
+ external_copies = Ext} ->
+ [] =:= (DC ++ (DOC ++ Ext)) -- [node()];
+ _ ->
+ false
+ end,
if
ReadNode == node() ->
%% Already loaded locally
@@ -2172,6 +2167,8 @@ load_table_fun(#net_load{cstruct=Cs, table=Tab, reason=Reason, opt_reply_to=Repl
end;
AccessMode == read_only, not AddTableCopy ->
fun() -> disc_load_table(Tab, Reason, ReplyTo) end;
+ Active =:= [], AddTableCopy, OnlyRamCopies ->
+ fun() -> disc_load_table(Tab, Reason, ReplyTo) end;
true ->
fun() ->
%% Either we cannot read the table yet
diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl
index f0ed7aef4a..cb2ee504f9 100644
--- a/lib/mnesia/src/mnesia_dumper.erl
+++ b/lib/mnesia/src/mnesia_dumper.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -67,10 +67,10 @@ get_log_writes() ->
incr_log_writes() ->
Left = mnesia_lib:incr_counter(trans_log_writes_left, -1),
if
- Left > 0 ->
- ignore;
+ Left =:= 0 ->
+ adjust_log_writes(true);
true ->
- adjust_log_writes(true)
+ ignore
end.
adjust_log_writes(DoCast) ->
@@ -191,8 +191,7 @@ do_perform_dump(Cont, InPlace, InitBy, Regulator, OldVersion) ->
try insert_recs(Recs, InPlace, InitBy, Regulator, OldVersion) of
Version ->
do_perform_dump(C2, InPlace, InitBy, Regulator, Version)
- catch _:R when R =/= fatal ->
- ST = erlang:get_stacktrace(),
+ catch _:R:ST when R =/= fatal ->
Reason = {"Transaction log dump error: ~tp~n", [{R, ST}]},
close_files(InPlace, {error, Reason}, InitBy),
exit(Reason)
@@ -325,8 +324,7 @@ perform_update(Tid, SchemaOps, _DumperMode, _UseDir) ->
?eval_debug_fun({?MODULE, post_dump}, [InitBy]),
close_files(InPlace, ok, InitBy),
ok
- catch _:Reason when Reason =/= fatal ->
- ST = erlang:get_stacktrace(),
+ catch _:Reason:ST when Reason =/= fatal ->
Error = {error, {"Schema update error", {Reason, ST}}},
close_files(InPlace, Error, InitBy),
fatal("Schema update error ~tp ~tp", [{Reason,ST}, SchemaOps])
@@ -1471,8 +1469,9 @@ regulate(RegulatorPid) ->
{regulated, RegulatorPid} -> ok
end.
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
Value -> Value
end.
diff --git a/lib/mnesia/src/mnesia_frag.erl b/lib/mnesia/src/mnesia_frag.erl
index c39f30e140..8f7dd321b0 100644
--- a/lib/mnesia/src/mnesia_frag.erl
+++ b/lib/mnesia/src/mnesia_frag.erl
@@ -1,7 +1,7 @@
%%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1157,9 +1157,10 @@ remove_node(Node, Cs) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Helpers
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
Value -> Value
end.
diff --git a/lib/mnesia/src/mnesia_index.erl b/lib/mnesia/src/mnesia_index.erl
index d121bd01e9..098265d5fc 100644
--- a/lib/mnesia/src/mnesia_index.erl
+++ b/lib/mnesia/src/mnesia_index.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -155,7 +155,7 @@ del_object_bag_([IxK|IxKs], Found, Type, Tab, Key, Obj, Ixt) ->
bag ->
db_match_erase(Ixt, {IxK, Key});
ordered ->
- db_erase(Ixt, {{IxK, Key}})
+ db_erase(Ixt, {IxK, Key})
end;
_ ->
ok
diff --git a/lib/mnesia/src/mnesia_late_loader.erl b/lib/mnesia/src/mnesia_late_loader.erl
index e4f8dcf2b9..45afda6e4b 100644
--- a/lib/mnesia/src/mnesia_late_loader.erl
+++ b/lib/mnesia/src/mnesia_late_loader.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl
index 53fdd76de8..a884b8e086 100644
--- a/lib/mnesia/src/mnesia_lib.erl
+++ b/lib/mnesia/src/mnesia_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -116,7 +116,7 @@
lock_table/1,
mkcore/1,
not_active_here/1,
- other_val/1,
+ other_val/2,
overload_read/0,
overload_read/1,
overload_set/2,
@@ -435,8 +435,8 @@ validate_record(Tab, Obj) ->
%%
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> other_val(Var, Stacktrace);
_VaLuE_ -> _VaLuE_
end.
@@ -446,9 +446,9 @@ set(Var, Val) ->
unset(Var) ->
?ets_delete(mnesia_gvar, Var).
-other_val(Var) ->
+other_val(Var, Stacktrace) ->
case other_val_1(Var) of
- error -> pr_other(Var);
+ error -> pr_other(Var, Stacktrace);
Val -> Val
end.
@@ -460,8 +460,8 @@ other_val_1(Var) ->
_ -> error
end.
--spec pr_other(_) -> no_return().
-pr_other(Var) ->
+-spec pr_other(_, _) -> no_return().
+pr_other(Var, Stacktrace) ->
Why =
case is_running() of
no -> {node_not_running, node()};
@@ -469,7 +469,7 @@ pr_other(Var) ->
end,
verbose("~p (~tp) val(mnesia_gvar, ~tw) -> ~p ~tp ~n",
[self(), process_info(self(), registered_name),
- Var, Why, erlang:get_stacktrace()]),
+ Var, Why, Stacktrace]),
mnesia:abort(Why).
%% Some functions for list valued variables
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 4c6336cb73..2cdae0c906 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,9 +34,10 @@
-include("mnesia.hrl").
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
Value -> Value
end.
@@ -66,7 +67,7 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_copies ->
EtsOpts = proplists:get_value(ets, StorageProps, []),
Args = [{keypos, 2}, public, named_table, Type | EtsOpts],
case Reason of
- {dumper, _} -> %% Resources already allocated
+ {dumper, DR} when is_atom(DR) -> %% Resources already allocated
ignore;
_ ->
mnesia_monitor:mktab(Tab, Args),
@@ -90,8 +91,8 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == ram_copies ->
EtsOpts = proplists:get_value(ets, StorageProps, []),
Args = [{keypos, 2}, public, named_table, Type | EtsOpts],
case Reason of
- {dumper, _} -> %% Resources allready allocated
- ignore;
+ {dumper, DR} when is_atom(DR) ->
+ ignore; %% Resources already allocated
_ ->
mnesia_monitor:mktab(Tab, Args),
Fname = mnesia_lib:tab2dcd(Tab),
@@ -130,7 +131,7 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_only_copies -
{repair, mnesia_monitor:get_env(auto_repair)}
| DetsOpts],
case Reason of
- {dumper, _} ->
+ {dumper, DR} when is_atom(DR) ->
mnesia_index:init_index(Tab, Storage),
snmpify(Tab, Storage),
set({Tab, load_node}, node()),
@@ -535,7 +536,7 @@ init_table(Tab, _, Fun, _DetsInfo,_) ->
try
true = ets:init_table(Tab, Fun),
ok
- catch _:Else -> {Else, erlang:get_stacktrace()}
+ catch _:Else:Stacktrace -> {Else, Stacktrace}
end.
@@ -777,9 +778,9 @@ do_send_table(Pid, Tab, Storage, RemoteS) ->
throw:receiver_died ->
cleanup_tab_copier(Pid, Storage, Tab),
ok;
- error:Reason -> %% Prepare failed
+ error:Reason:Stacktrace -> %% Prepare failed
cleanup_tab_copier(Pid, Storage, Tab),
- {error, {tab_copier, Tab, {Reason, erlang:get_stacktrace()}}}
+ {error, {tab_copier, Tab, {Reason, Stacktrace}}}
after
unlink(whereis(mnesia_tm))
end.
diff --git a/lib/mnesia/src/mnesia_locker.erl b/lib/mnesia/src/mnesia_locker.erl
index 073b48abc0..f68626413e 100644
--- a/lib/mnesia/src/mnesia_locker.erl
+++ b/lib/mnesia/src/mnesia_locker.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -97,10 +97,11 @@ init(Parent) ->
end,
loop(#state{supervisor = Parent}).
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
- _VaLuE_ -> _VaLuE_
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
+ Value -> Value
end.
reply(From, R) ->
diff --git a/lib/mnesia/src/mnesia_log.erl b/lib/mnesia/src/mnesia_log.erl
index a2de23a2a3..03411ace41 100644
--- a/lib/mnesia/src/mnesia_log.erl
+++ b/lib/mnesia/src/mnesia_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl
index d792070332..2ccea1ea6d 100644
--- a/lib/mnesia/src/mnesia_recover.erl
+++ b/lib/mnesia/src/mnesia_recover.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -177,10 +177,10 @@ disconnect(Node) ->
log_decision(D) ->
cast({log_decision, D}).
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _Reason} ->
- mnesia_lib:other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
Value -> Value
end.
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index 71952af31c..ef38adca1e 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -181,9 +181,10 @@ exit_on_error({error, Reason}) ->
exit_on_error(GoodRes) ->
GoodRes.
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
Value -> Value
end.
@@ -2695,10 +2696,10 @@ prepare_op(_Tid, {op, transform, Fun, TabDef}, _WaitFor) ->
Objs ->
mnesia_lib:db_fixtable(Storage, Tab, false),
{true, Objs, mandatory}
- catch _:Reason ->
+ catch _:Reason:Stacktrace ->
mnesia_lib:db_fixtable(Storage, Tab, false),
mnesia_lib:important("Transform function failed: '~tp' in '~tp'",
- [Reason, erlang:get_stacktrace()]),
+ [Reason, Stacktrace]),
exit({"Bad transform function", Tab, Fun, node(), Reason})
end
end;
diff --git a/lib/mnesia/src/mnesia_subscr.erl b/lib/mnesia/src/mnesia_subscr.erl
index dfaa20d2d3..21a308cfb6 100644
--- a/lib/mnesia/src/mnesia_subscr.erl
+++ b/lib/mnesia/src/mnesia_subscr.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/src/mnesia_text.erl b/lib/mnesia/src/mnesia_text.erl
index 7d24d09472..cc21621ff4 100644
--- a/lib/mnesia/src/mnesia_text.erl
+++ b/lib/mnesia/src/mnesia_text.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index ebf580d09e..4b3fffc735 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -121,10 +121,11 @@ init(Parent) ->
proc_lib:init_ack(Parent, {ok, self()}),
doit_loop(#state{supervisor = Parent}).
+%% Local function in order to avoid external function call
val(Var) ->
- case ?catch_val(Var) of
- {'EXIT', _} -> mnesia_lib:other_val(Var);
- _VaLuE_ -> _VaLuE_
+ case ?catch_val_and_stack(Var) of
+ {'EXIT', Stacktrace} -> mnesia_lib:other_val(Var, Stacktrace);
+ Value -> Value
end.
reply({From,Ref}, R) ->
@@ -597,9 +598,9 @@ recover_coordinator(Tid, Etabs) ->
false -> %% When killed before store havn't been copied to
ok %% to the new nested trans store.
end
- catch _:Reason ->
+ catch _:Reason:Stacktrace ->
dbg_out("Recovery of coordinator ~p failed: ~tp~n",
- [Tid, {Reason, erlang:get_stacktrace()}]),
+ [Tid, {Reason, Stacktrace}]),
Protocol = asym_trans,
tell_outcome(Tid, Protocol, node(), CheckNodes, TellNodes)
end,
@@ -825,8 +826,7 @@ execute_transaction(Fun, Args, Factor, Retries, Type) ->
catch throw:Value -> %% User called throw
Reason = {aborted, {throw, Value}},
return_abort(Fun, Args, Reason);
- error:Reason ->
- ST = erlang:get_stacktrace(),
+ error:Reason:ST ->
check_exit(Fun, Args, Factor, Retries, {Reason,ST}, Type);
_:Reason ->
check_exit(Fun, Args, Factor, Retries, Reason, Type)
@@ -1796,14 +1796,13 @@ do_update(Tid, Storage, [Op | Ops], OldRes) ->
try do_update_op(Tid, Storage, Op) of
ok -> do_update(Tid, Storage, Ops, OldRes);
NewRes -> do_update(Tid, Storage, Ops, NewRes)
- catch _:Reason ->
+ catch _:Reason:ST ->
%% This may only happen when we recently have
%% deleted our local replica, changed storage_type
%% or transformed table
%% BUGBUG: Updates may be lost if storage_type is changed.
%% Determine actual storage type and try again.
%% BUGBUG: Updates may be lost if table is transformed.
- ST = erlang:get_stacktrace(),
verbose("do_update in ~w failed: ~tp -> {'EXIT', ~tp}~n",
[Tid, Op, {Reason, ST}]),
do_update(Tid, Storage, Ops, OldRes)
@@ -1914,11 +1913,10 @@ commit_clear([H|R], Tid, Storage, Tab, K, Obj)
do_snmp(_, []) -> ok;
do_snmp(Tid, [Head|Tail]) ->
try mnesia_snmp_hook:update(Head)
- catch _:Reason ->
+ catch _:Reason:ST ->
%% This should only happen when we recently have
%% deleted our local replica or recently deattached
%% the snmp table
- ST = erlang:get_stacktrace(),
verbose("do_snmp in ~w failed: ~tp -> {'EXIT', ~tp}~n",
[Tid, Head, {Reason, ST}])
end,
@@ -2212,7 +2210,7 @@ display_pid_info(Pid) ->
Other
end,
Reds = fetch(reductions, Info),
- LM = length(fetch(messages, Info)),
+ LM = fetch(message_queue_len, Info),
pformat(io_lib:format("~p", [Pid]),
io_lib:format("~tp", [Call]),
io_lib:format("~tp", [Curr]), Reds, LM)
diff --git a/lib/mnesia/test/mnesia_SUITE.erl b/lib/mnesia/test/mnesia_SUITE.erl
index 279744dbb0..24c1def6da 100644
--- a/lib/mnesia/test/mnesia_SUITE.erl
+++ b/lib/mnesia/test/mnesia_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_atomicity_test.erl b/lib/mnesia/test/mnesia_atomicity_test.erl
index 58a5dc1d40..4764f9e7c0 100644
--- a/lib/mnesia/test/mnesia_atomicity_test.erl
+++ b/lib/mnesia/test/mnesia_atomicity_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_bench_SUITE.erl b/lib/mnesia/test/mnesia_bench_SUITE.erl
index 5cc01867c4..8a225629e6 100644
--- a/lib/mnesia/test/mnesia_bench_SUITE.erl
+++ b/lib/mnesia/test/mnesia_bench_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_consistency_test.erl b/lib/mnesia/test/mnesia_consistency_test.erl
index 7a2678cee3..46bafaf65c 100644
--- a/lib/mnesia/test/mnesia_consistency_test.erl
+++ b/lib/mnesia/test/mnesia_consistency_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_cost.erl b/lib/mnesia/test/mnesia_cost.erl
index 4d0dd7b0ee..b5d5253147 100644
--- a/lib/mnesia/test/mnesia_cost.erl
+++ b/lib/mnesia/test/mnesia_cost.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_dirty_access_test.erl b/lib/mnesia/test/mnesia_dirty_access_test.erl
index 92124ebc65..67ef1fe901 100644
--- a/lib/mnesia/test/mnesia_dirty_access_test.erl
+++ b/lib/mnesia/test/mnesia_dirty_access_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_durability_test.erl b/lib/mnesia/test/mnesia_durability_test.erl
index 2fac5cac82..ccbfdc9738 100644
--- a/lib/mnesia/test/mnesia_durability_test.erl
+++ b/lib/mnesia/test/mnesia_durability_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -46,6 +46,7 @@
master_nodes/1, starting_master_nodes/1,
master_on_non_local_tables/1,
remote_force_load_with_local_master_node/1,
+ master_node_with_ram_copy_2/1, master_node_with_ram_copy_3/1,
dump_ram_copies/1, dump_disc_copies/1, dump_disc_only/1]).
-include("mnesia_test_lib.hrl").
@@ -91,7 +92,8 @@ groups() ->
{load_tables_with_master_tables, [],
[master_nodes, starting_master_nodes,
master_on_non_local_tables,
- remote_force_load_with_local_master_node]},
+ remote_force_load_with_local_master_node,
+ master_node_with_ram_copy_2, master_node_with_ram_copy_3]},
{durability_of_dump_tables, [],
[dump_ram_copies, dump_disc_copies, dump_disc_only]}].
@@ -1165,6 +1167,107 @@ remote_force_load_with_local_master_node(Config) when is_list(Config) ->
?verify_mnesia(Nodes, []).
+master_node_with_ram_copy_2(Config) when is_list(Config) ->
+ [A, B] = Nodes = ?acquire_nodes(2, Config),
+ Tab = ?FUNCTION_NAME,
+ ?match({atomic,ok}, mnesia:create_table(Tab, [{disc_copies, [A]}, {ram_copies, [B]}])),
+ ?match({atomic,ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ %% Test that we don't load from ram_copies
+ ?match(stopped, rpc:call(A, mnesia, stop, [])),
+ ?match(stopped, rpc:call(B, mnesia, stop, [])),
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 1000])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match([{Tab, 1, init}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, init}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test that master_nodes set to ram_copy node require force_load
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [[B]])),
+ ?match(stopped, rpc:call(A, mnesia, stop, [])),
+ ?match(stopped, rpc:call(B, mnesia, stop, [])),
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 1000])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 1000])),
+
+ ?match(yes, rpc:call(A, mnesia, force_load_table, [Tab])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 1000])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 1000])),
+ ?match([{Tab, 1, init}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, init}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+
+ ?verify_mnesia(Nodes, []).
+
+
+master_node_with_ram_copy_3(Config) when is_list(Config) ->
+ [A, B, C] = Nodes = ?acquire_nodes(3, Config),
+ Tab = ?FUNCTION_NAME,
+ ?match({atomic,ok}, mnesia:create_table(Tab, [{disc_copies, [A,C]}, {ram_copies, [B]}])),
+ ?match({atomic,ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+
+ %% Test that we don't load from ram_copies
+ ?match(stopped, rpc:call(A, mnesia, stop, [])),
+ ?match(stopped, rpc:call(C, mnesia, stop, [])),
+ ?match(stopped, rpc:call(B, mnesia, stop, [])),
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 1000])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match(ok, rpc:call(C, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match([{Tab, 1, init}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, init}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, init}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test that master_nodes set to ram_copy node will wait until loaded
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [[B]])),
+ ?match(stopped, rpc:call(A, mnesia, stop, [])),
+ ?match({atomic,ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, update})])),
+ ?match(stopped, rpc:call(C, mnesia, stop, [])),
+ ?match({atomic,ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, ram_copies})])),
+ ?match(stopped, rpc:call(B, mnesia, stop, [])),
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 500])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 500])),
+ ?match(ok, rpc:call(C, mnesia, start, [])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match([{Tab, 1, update}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, update}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, update}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ %% Test that master_nodes set to ram_copy node requires force load
+ ?match({atomic,ok}, mnesia:sync_transaction(?SDwrite({Tab, 1, init}))),
+ ?match(ok, rpc:call(A, mnesia, set_master_nodes, [[B]])),
+ ?match(ok, rpc:call(C, mnesia, set_master_nodes, [[B]])),
+
+ ?match(stopped, rpc:call(A, mnesia, stop, [])),
+ ?match({atomic,ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, update})])),
+ ?match(stopped, rpc:call(C, mnesia, stop, [])),
+ ?match({atomic,ok}, rpc:call(B, mnesia, sync_transaction, [?SDwrite({Tab, 1, ram_copies})])),
+ ?match(stopped, rpc:call(B, mnesia, stop, [])),
+ ?match(ok, rpc:call(B, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 500])),
+ ?match(ok, rpc:call(A, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 500])),
+ ?match(ok, rpc:call(C, mnesia, start, [])),
+ ?match({timeout, [Tab]}, rpc:call(A, mnesia, wait_for_tables, [[Tab], 500])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 500])),
+ ?match({timeout, [Tab]}, rpc:call(B, mnesia, wait_for_tables, [[Tab], 500])),
+ ?match(yes, rpc:call(C, mnesia, force_load_table, [Tab])),
+
+ ?match(ok, rpc:call(A, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match(ok, rpc:call(B, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match(ok, rpc:call(C, mnesia, wait_for_tables, [[Tab], 3000])),
+ ?match([{Tab, 1, update}], rpc:call(A, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, update}], rpc:call(B, mnesia, dirty_read, [{Tab, 1}])),
+ ?match([{Tab, 1, update}], rpc:call(C, mnesia, dirty_read, [{Tab, 1}])),
+
+ ?verify_mnesia(Nodes, []).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1415,7 +1518,7 @@ do_disc_durability(Config,CopyType) ->
[{Tab_bag, 22, a_2222}], [{Tab_bag, 33, a_3333}],
[{Tab_set, counter, 10}]]),
- timer:sleep(1000), %% Debugging strange msgs..
+ timer:sleep(500), %% Debugging strange msgs..
?log("Flushed ~p ~n", [mnesia_test_lib:flush()]),
?verify_mnesia(Nodes, []).
diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl
index 074967469b..a451c8d0c8 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-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,10 +31,11 @@
db_node_lifecycle/1, evil_delete_db_node/1, start_and_stop/1,
checkpoint/1, table_lifecycle/1, storage_options/1,
add_copy_conflict/1, add_copy_when_going_down/1,
+ add_copy_with_down/1,
replica_management/1, clear_table_during_load/1,
schema_availability/1, local_content/1,
replica_location/1, user_properties/1, unsupp_user_props/1,
- sorted_ets/1,
+ sorted_ets/1, index_cleanup/1,
change_table_access_mode/1, change_table_load_order/1,
set_master_nodes/1, offline_set_master_nodes/1,
dump_tables/1, dump_log/1, wait_for_tables/1, force_load_table/1,
@@ -48,7 +49,7 @@
record_name_dirty_access_disc_only/1,
record_name_dirty_access_xets/1]).
--export([info_check/8]).
+-export([info_check/8, index_size/1]).
-define(cleanup(N, Config),
mnesia_test_lib:prepare_test_case([{reload_appls, [mnesia]}],
@@ -65,13 +66,14 @@ 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, clear_table_during_load,
+ add_copy_when_going_down, add_copy_with_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,
{group, record_name}, {group, snmp_access},
{group, subscriptions}, {group, iteration},
- {group, debug_support}, sorted_ets,
+ {group, debug_support}, sorted_ets, index_cleanup,
{mnesia_dirty_access_test, all},
{mnesia_trans_access_test, all},
{mnesia_evil_backup, all}].
@@ -732,6 +734,49 @@ add_copy_when_going_down(Config) ->
?match_receive({test,{aborted,_}}),
?verify_mnesia([Node2], []).
+add_copy_with_down(suite) -> [];
+add_copy_with_down(Config) ->
+ %% Allow add_table_copy() with ram_copies even all other replicas are down
+ Nodes = [Node1, Node2, Node3] = ?acquire_nodes(3, Config),
+ ?match({atomic, ok}, mnesia:create_table(a, [{ram_copies, [Node3]}, {disc_copies, [Node2]}])),
+ stopped = rpc:call(Node2, mnesia, stop, []),
+ stopped = rpc:call(Node3, mnesia, stop, []),
+ ?match({aborted, _}, mnesia:add_table_copy(a, Node1, ram_copies)),
+ ?match({aborted, _}, mnesia:del_table_copy(a, Node2)),
+ ok = rpc:call(Node3, mnesia, start, []),
+ ?match({aborted, _}, mnesia:add_table_copy(a, Node1, ram_copies)),
+ ?match([], mnesia_test_lib:start_mnesia([Node2], [a])),
+ ?match({atomic, ok}, mnesia:change_table_copy_type(a, Node2, ram_copies)),
+ stopped = rpc:call(Node2, mnesia, stop, []),
+ stopped = rpc:call(Node3, mnesia, stop, []),
+ ?match({atomic, ok}, mnesia:add_table_copy(a, Node1, ram_copies)),
+ ?match(ok, mnesia:dirty_write({a,1,1})),
+ ?match([], mnesia_test_lib:start_mnesia([Node2,Node3], [a])),
+ ?match([{a,1,1}], rpc:call(Node1, mnesia, dirty_read, [{a,1}])),
+ ?match([{a,1,1}], rpc:call(Node2, mnesia, dirty_read, [{a,1}])),
+ ?match([{a,1,1}], rpc:call(Node3, mnesia, dirty_read, [{a,1}])),
+
+ ?match({atomic, ok}, mnesia:del_table_copy(a, Node1)),
+ stopped = rpc:call(Node2, mnesia, stop, []),
+ stopped = rpc:call(Node3, mnesia, stop, []),
+ ?match({atomic, ok}, mnesia:add_table_copy(a, Node1, disc_copies)),
+ ?match(ok, mnesia:dirty_write({a,1,1})),
+ ?match([], mnesia_test_lib:start_mnesia([Node2,Node3], [a])),
+ ?match([{a,1,1}], rpc:call(Node1, mnesia, dirty_read, [{a,1}])),
+ ?match([{a,1,1}], rpc:call(Node2, mnesia, dirty_read, [{a,1}])),
+ ?match([{a,1,1}], rpc:call(Node3, mnesia, dirty_read, [{a,1}])),
+
+ ?match({atomic, ok}, mnesia:del_table_copy(a, Node1)),
+ stopped = rpc:call(Node2, mnesia, stop, []),
+ stopped = rpc:call(Node3, mnesia, stop, []),
+ ?match({atomic, ok}, mnesia:add_table_copy(a, Node1, disc_only_copies)),
+ ?match(ok, mnesia:dirty_write({a,1,1})),
+ ?match([], mnesia_test_lib:start_mnesia([Node2,Node3], [a])),
+ ?match([{a,1,1}], rpc:call(Node1, mnesia, dirty_read, [{a,1}])),
+ ?match([{a,1,1}], rpc:call(Node2, mnesia, dirty_read, [{a,1}])),
+ ?match([{a,1,1}], rpc:call(Node3, mnesia, dirty_read, [{a,1}])),
+
+ ?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Add, drop and move replicas, change storage types
@@ -2514,3 +2559,55 @@ sorted_ets(Config) when is_list(Config) ->
?match({atomic, [{rec,1,1}, {rec,2,1}]}, mnesia:transaction(TestIt)).
+index_cleanup(Config) when is_list(Config) ->
+ [N1, N2] = All = ?acquire_nodes(2, Config),
+ ?match({atomic, ok}, mnesia:create_table(i_set, [{type, set}, {ram_copies, [N1]}, {index, [val]},
+ {disc_only_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(i_bag, [{type, bag}, {ram_copies, [N1]}, {index, [val]},
+ {disc_only_copies, [N2]}])),
+ ?match({atomic, ok}, mnesia:create_table(i_oset, [{type, ordered_set}, {ram_copies, [N1, N2]},
+ {index, [val]}])),
+
+ Tabs = [i_set, i_bag, i_oset],
+
+ Add = fun(Tab) ->
+ Write = fun(Tab) ->
+ Recs = [{Tab, N, N rem 5} || N <- lists:seq(1,10)],
+ [ok = mnesia:write(Rec) || Rec <- Recs],
+ Recs
+ end,
+ {atomic, Recs} = mnesia:sync_transaction(Write, [Tab]),
+ lists:sort(Recs)
+ end,
+
+ IRead = fun(Tab) ->
+ Read = fun(Tab) ->
+ [mnesia:index_read(Tab, N, val) || N <- lists:seq(0,4)]
+ end,
+ {atomic, Recs} = mnesia:transaction(Read, [Tab]),
+ lists:sort(lists:flatten(Recs))
+ end,
+
+ Delete = fun(Rec) ->
+ Del = fun() -> mnesia:delete_object(Rec) end,
+ {atomic, ok} = mnesia:sync_transaction(Del),
+ ok
+ end,
+
+
+ Recs = [Add(Tab) || Tab <- Tabs],
+ ?match(Recs, [IRead(Tab) || Tab <- Tabs]),
+ [Delete(Rec) || Rec <- lists:flatten(Recs)],
+
+ [?match({Tab,0}, {Tab,mnesia:table_info(Tab, size)}) || Tab <- Tabs],
+
+ [?match({Tab,Node,0, _}, rpc:call(Node, ?MODULE, index_size, [Tab]))
+ || Node <- All, Tab <- Tabs],
+ ?verify_mnesia(All, []).
+
+index_size(Tab) ->
+ %% White box testing
+ case mnesia:table_info(Tab, index_info) of
+ {index, _, [{_, {ram, Ref}}=Dbg]} -> {Tab, node(), ets:info(Ref, size), Dbg};
+ {index, _, [{_, {dets, Ref}}=Dbg]} -> {Tab, node(), dets:info(Ref, size), Dbg}
+ end.
diff --git a/lib/mnesia/test/mnesia_examples_test.erl b/lib/mnesia/test/mnesia_examples_test.erl
index f1259abf90..3bbb6e4d77 100644
--- a/lib/mnesia/test/mnesia_examples_test.erl
+++ b/lib/mnesia/test/mnesia_examples_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_frag_test.erl b/lib/mnesia/test/mnesia_frag_test.erl
index 7371792fda..7b37fcb684 100644
--- a/lib/mnesia/test/mnesia_frag_test.erl
+++ b/lib/mnesia/test/mnesia_frag_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_install_test.erl b/lib/mnesia/test/mnesia_install_test.erl
index 3f67396eb0..2aee5137c3 100644
--- a/lib/mnesia/test/mnesia_install_test.erl
+++ b/lib/mnesia/test/mnesia_install_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index 1c3ea5ec92..49bcec14af 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1563,7 +1563,8 @@ trans_update_visible_inside_trans(Config) when is_list(Config) ->
?match({atomic, ok}, mnesia:create_table([{name, Tab},
{ram_copies, [Node1]}])),
ValPos = 3,
- RecA = {Tab, a, 1},
+ RecA = {Tab, a, 1},
+ RecA2 = {Tab, a, 2},
PatA = {Tab, '$1', 1},
RecB = {Tab, b, 3},
PatB = {Tab, '$1', 3},
@@ -1598,6 +1599,14 @@ trans_update_visible_inside_trans(Config) when is_list(Config) ->
?match([], mnesia:index_read(Tab, 3, ValPos)),
%% delete_object
+ ?match(ok, mnesia:delete_object(RecA2)),
+ ?match([RecA], mnesia:read({Tab, a})),
+ ?match([RecA], mnesia:wread({Tab, a})),
+ ?match([RecA], mnesia:match_object(PatA)),
+ ?match([a], mnesia:all_keys(Tab)),
+ ?match([RecA], mnesia:index_match_object(PatA, ValPos)),
+ ?match([RecA], mnesia:index_read(Tab, 1, ValPos)),
+
?match(ok, mnesia:delete_object(RecA)),
?match([], mnesia:read({Tab, a})),
?match([], mnesia:wread({Tab, a})),
diff --git a/lib/mnesia/test/mnesia_majority_test.erl b/lib/mnesia/test/mnesia_majority_test.erl
index eb82617b60..aae27e069e 100644
--- a/lib/mnesia/test/mnesia_majority_test.erl
+++ b/lib/mnesia/test/mnesia_majority_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_measure_test.erl b/lib/mnesia/test/mnesia_measure_test.erl
index 4e63eaee22..8eb3590168 100644
--- a/lib/mnesia/test/mnesia_measure_test.erl
+++ b/lib/mnesia/test/mnesia_measure_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_nice_coverage_test.erl b/lib/mnesia/test/mnesia_nice_coverage_test.erl
index 7c96d6e6a0..f8c6b2ce20 100644
--- a/lib/mnesia/test/mnesia_nice_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_nice_coverage_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_qlc_test.erl b/lib/mnesia/test/mnesia_qlc_test.erl
index 262a6b4abc..e66fd84995 100644
--- a/lib/mnesia/test/mnesia_qlc_test.erl
+++ b/lib/mnesia/test/mnesia_qlc_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_recovery_test.erl b/lib/mnesia/test/mnesia_recovery_test.erl
index 82d6e6ac6a..b5749408f8 100644
--- a/lib/mnesia/test/mnesia_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_recovery_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -730,6 +730,7 @@ do_trans_loop2(Tab, Father) ->
do_trans_loop2(Tab, Father);
Else ->
?error("Transaction failed: ~p ~n", [Else]),
+ io:format("INFO: ~p~n",[erlang:process_info(self())]),
Father ! test_done,
exit(shutdown)
end.
diff --git a/lib/mnesia/test/mnesia_registry_test.erl b/lib/mnesia/test/mnesia_registry_test.erl
index 08157f1be3..c15b8e97af 100644
--- a/lib/mnesia/test/mnesia_registry_test.erl
+++ b/lib/mnesia/test/mnesia_registry_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_schema_recovery_test.erl b/lib/mnesia/test/mnesia_schema_recovery_test.erl
index 5e7627ca47..e4199758c1 100644
--- a/lib/mnesia/test/mnesia_schema_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_schema_recovery_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 0fabdc7929..1cdac3cde6 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -470,9 +470,9 @@ get_suite(Mod, {group, Suite}) ->
{_, _, TCList} = lists:keyfind(Suite, 1, Groups),
TCList
catch
- _:Reason ->
+ _:Reason:Stacktrace ->
io:format("Not implemented ~p ~p (~p ~p)~n",
- [Mod,Suite,Reason, erlang:get_stacktrace()]),
+ [Mod,Suite,Reason,Stacktrace]),
'NYI'
end;
get_suite(Mod, all) ->
@@ -774,7 +774,7 @@ init_nodes([], _File, _Line) ->
%% Returns [Name, Host]
node_to_name_and_host(Node) ->
- string:tokens(atom_to_list(Node), [$@]).
+ string:lexemes(atom_to_list(Node), [$@]).
lookup_config(Key,Config) ->
case lists:keysearch(Key,1,Config) of
diff --git a/lib/mnesia/test/mnesia_test_lib.hrl b/lib/mnesia/test/mnesia_test_lib.hrl
index ba7eb10ea2..b8eeb5783f 100644
--- a/lib/mnesia/test/mnesia_test_lib.hrl
+++ b/lib/mnesia/test/mnesia_test_lib.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -55,25 +55,25 @@
?error("Not Matching Actual result was:~n ~p~n",[_AR_0]),
{fail,_AR_0}
catch
- exit:{aborted, _ER_1} when
+ exit:{aborted, _ER_1}:Stacktrace when
element(1, _ER_1) =:= node_not_running;
element(1, _ER_1) =:= bad_commit;
element(1, _ER_1) =:= cyclic ->
%% Need to re-raise these to restart transaction
- erlang:raise(exit, {aborted, _ER_1}, erlang:get_stacktrace());
- exit:_AR_1 ->
+ erlang:raise(exit, {aborted, _ER_1}, Stacktrace);
+ exit:_AR_1:Stacktrace ->
case fun(_AR_EXIT_) -> {'EXIT', _AR_EXIT_} end(_AR_1) of
_AR_2 = ExpectedRes ->
?verbose("ok, ~n Result as expected:~p~n",[_AR_2]),
{success,_AR_2};
_AR_2 ->
?error("Not Matching Actual result was:~n ~p~n ~p~n",
- [_AR_2, erlang:get_stacktrace()]),
+ [_AR_2, Stacktrace]),
{fail,_AR_2}
end;
- _T1_:_AR_1 ->
+ _T1_:_AR_1:Stacktrace ->
?error("Not Matching Actual result was:~n ~p~n ~p~n",
- [{_T1_,_AR_1}, erlang:get_stacktrace()]),
+ [{_T1_,_AR_1}, Stacktrace]),
{fail,{_T1_,_AR_1}}
end
end()).
diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl
index c00a1ed51f..723a85fd2c 100644
--- a/lib/mnesia/test/mnesia_trans_access_test.erl
+++ b/lib/mnesia/test/mnesia_trans_access_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index 45f811846d..781a4830a0 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.15.3
+MNESIA_VSN = 4.15.6