Listed below are some of the most important and attractive capabilities, Mnesia provides:
A relational/object hybrid data model which is suitable for telecommunications applications.
A specifically designed DBMS query language, QLC (as an add-on library).
Persistence. Tables may be coherently kept on disc as well as in main memory.
Replication. Tables may be replicated at several nodes.
Atomic transactions. A series of table manipulation operations can be grouped into a single atomic transaction.
Location transparency. Programs can be written without knowledge of the actual location of data.
Extremely fast real time data searches.
Schema manipulation routines. It is possible to reconfigure the DBMS at runtime without stopping the system.
This Reference Manual describes the Mnesia API. This includes functions used to define and manipulate Mnesia tables.
All functions documented in these pages can be used in any combination with queries using the list comprehension notation. The query notation is described in the QLC's man page.
Data in Mnesia is organized as a set of tables. Each table has a name which must be an atom. Each table is made up of Erlang records. The user is responsible for the record definitions. Each table also has a set of properties. Below are some of the properties that are associated with each table:
If a new item is inserted with the same key as
an existing record, the old record is overwritten. On the
other hand, if a table is of type 'bag', each key can map to
several records. However, all records in type bag tables are
unique, only the keys may be duplicated.
See
This document uses a table of persons to illustrate various examples. The following record definition is assumed:
-record(person, {name,
age = 0,
address = unknown,
salary = 0,
children = []}),
The first attribute of the record is the primary key, or key for short.
The function descriptions are sorted in alphabetic order. Hint:
start to read about
Writing or deleting in transaction context creates a local copy
of each modified record during the transaction. During iteration,
i.e.
Makes the transaction silently
return the tuple
A checkpoint is a consistent view of the system. A checkpoint can be activated on a set of tables. This checkpoint can then be traversed and will present a view of the system as it existed at the time when the checkpoint was activated, even if the tables are being or have been manipulated.
Returns
Invokes
This function executes the functional object
The code which executes inside the activity can
consist of a series of table manipulation functions, which is
performed in a
Short for
Invokes
Short for
Invokes
Invokes
Invokes
Invokes
This function (
Mnesia will forward calls to the following functions:
mnesia:lock/2 (read_lock_table/1, write_lock_table/1)
mnesia:write/3 (write/1, s_write/1)
mnesia:delete/3 (delete/1, s_delete/1)
mnesia:delete_object/3 (delete_object/1, s_delete_object/1)
mnesia:read/3 (read/1, wread/1)
mnesia:match_object/3 (match_object/1)
mnesia:all_keys/1
mnesia:first/1
mnesia:last/1
mnesia:prev/2
mnesia:next/2
mnesia:index_match_object/4 (index_match_object/2)
mnesia:index_read/3
mnesia:table_info/2
to the corresponding:
AccessMod:lock(ActivityId, Opaque, LockItem, LockKind)
AccessMod:write(ActivityId, Opaque, Tab, Rec, LockKind)
AccessMod:delete(ActivityId, Opaque, Tab, Key, LockKind)
AccessMod:delete_object(ActivityId, Opaque, Tab, RecXS, LockKind)
AccessMod:read(ActivityId, Opaque, Tab, Key, LockKind)
AccessMod:match_object(ActivityId, Opaque, Tab, Pattern, LockKind)
AccessMod:all_keys(ActivityId, Opaque, Tab, LockKind)
AccessMod:first(ActivityId, Opaque, Tab)
AccessMod:last(ActivityId, Opaque, Tab)
AccessMod:prev(ActivityId, Opaque, Tab, Key)
AccessMod:next(ActivityId, Opaque, Tab, Key)
AccessMod:index_match_object(ActivityId, Opaque, Tab, Pattern, Attr, LockKind)
AccessMod:index_read(ActivityId, Opaque, Tab, SecondaryKey, Attr, LockKind)
AccessMod:table_info(ActivityId, Opaque, Tab, InfoItem)
where
This function makes another copy of a table at the
node
mnesia:add_table_copy(person, Node, disc_copies)
This function can also be used to add a replica of the
table named
Table indices can and should be used whenever the user wants to frequently use some other field than the key field to look up records. If this other field has an index associated with it, these lookups can occur in constant time and space. For example, if our application wishes to use the age field of persons to efficiently find all person with a specific age, it might be a good idea to have an index on the age field. This can be accomplished with the following call:
mnesia:add_table_index(person, age)
Indices do not come free, they occupy space which is proportional to the size of the table. They also cause insertions into the table to execute slightly slower.
This function returns a list of all keys in the table
named
Call the
It is possible to manipulate the Mnesia tables without using transactions. This has some serious disadvantages, but is considerably faster since the transaction manager is not involved and no locks are set. A dirty operation does, however, guarantee a certain level of consistency and it is not possible for the dirty operations to return garbled records. All dirty operations provide location transparency to the programmer and a program does not have to be aware of the whereabouts of a certain table in order to function.
Note:It is more than 10 times more efficient to read records dirty than within a transaction.
Depending on the application, it may be a good idea to use the dirty functions for certain operations. Almost all Mnesia functions which can be called within transactions have a dirty equivalent which is much more efficient. However, it must be noted that it is possible for the database to be left in an inconsistent state if dirty operations are used to update it. Dirty operations should only be used for performance reasons when it is absolutely necessary.
Note: Calling (nesting) a
Activates a new checkpoint covering all Mnesia tables,
including the schema, with maximum degree of redundancy and
performs a backup using
The tables are backed up to external media using the backup
module
The
Note: This function shall only be used to connect to newly started ram nodes
(N.D.R.S.N.) with an empty schema. If for example it is used after the network
have been partitioned it may lead to inconsistent tables.
Note: Mnesia may be connected to other nodes than those
returned in
The
For example:
mnesia:change_table_copy_type(person, node(), disc_copies)
Transforms our
This function can also be used to change the storage type of
the table named
The
Deletes all entries in the table
Creates a new database on disc. Various files are created in the local Mnesia directory of each node. Note that the directory must be unique for each node. Two nodes may never share the same directory. If possible, use a local disc device in order to improve performance.
Note: Only nodes with disc should be
included in
This function creates a Mnesia table called
At startup Mnesia always loads
When accessing single attributes in a record, it is not
necessary, or even recommended, to hard code any
attribute names as atoms. Use the construct
It is possible
to have a replicated table of type
For example, the following call creates the
mnesia:create_table(person,
[{ram_copies, [N1, N2]},
{attributes, record_info(fields,person)}]).
If it was required that Mnesia build and maintain an extra index
table on the
mnesia:create_table(person,
[{ram_copies, [N1, N2]},
{index, [address]},
{attributes, record_info(fields,person)}]).
The specification of
The checkpoint is automatically deactivated when some of
the tables involved have no retainer attached to them. This may
happen when nodes go down or when a replica is deleted.
Checkpoints will also be deactivated with this function.
Deletes the replica of table
This function may also be used to delete a replica of
the table named
This function deletes the index on attribute with name
Invokes
Deletes all records in table
The semantics of this function is context sensitive. See
Invokes
If a table is of type
The semantics of this function is context sensitive. See
Deletes a database created with
After the database has been deleted, it may still be
possible to start Mnesia as a disc-less node. This depends on
how the configuration parameter
This function must be used with extreme caution since it makes existing persistent data obsolete. Think twice before using it.
Permanently deletes all replicas of table
This is the dirty equivalent of the
Invokes
This is the dirty equivalent of the
Invokes
This is the dirty equivalent of the
Records in
If there are no records at all in the table, this function
returns the atom
Invokes
This is the dirty equivalent of the
This is the dirty equivalent of the
This function works exactly
Invokes
This is the dirty equivalent of the
This function makes it possible to traverse a table
and perform operations on all records in the table. When
the end of the table is reached, the special key
This function works exactly
Invokes
This is the dirty equivalent of the
This is the dirty equivalent of the
This function can be used to traverse a table in a
manner similar to the
Invokes
There are no special counter records in Mnesia. However,
records of the form
If two processes perform
If
Invokes
This is the dirty equivalent of
Performs a user initiated dump of the local log file. This is usually not necessary since Mnesia, by default, manages this automatically.
This function dumps a set of
Dumps all local tables of a mnesia system into a text file
which can then be edited (by means of a normal text editor)
and then later be reloaded with
All Mnesia transactions, including all the schema
update functions, either return the value
The
Call the
Note: Calling (nesting) a
Records in
If there are no records at all in the table, this function
returns the atom
Iterates over the table
This function works exactly as
The Mnesia algorithm for table load might lead to a situation where a table cannot be loaded. This situation occurs when a node is started and Mnesia concludes, or suspects, that another copy of the table was active after this local copy became inactive due to a system crash.
If this situation is not acceptable, this function can be used to override the strategy of the Mnesia table load algorithm. This could lead to a situation where some transaction effects are lost with a inconsistent database as result, but for some applications high availability is more important than consistent data.
Invokes
In a manner similar to the
The table
The element in position
The two index search functions described here are
automatically invoked when searching tables with
The semantics of this function is context sensitive. See
Assume there is an index on position
The semantics of this function is context sensitive. See
Prints some information about the system on the tty. This function may be used even if Mnesia is not started. However, more information will be displayed if Mnesia is started.
Invokes
Invokes
This function is used to install a backup as fallback. The fallback will be used to restore the database at the next start-up. Installation of fallbacks requires Erlang to be up and running on all the involved nodes, but it does not matter if Mnesia is running or not. The installation of the fallback will fail if the local node is not one of the disc resident nodes in the backup.
If the
This is a somewhat dangerous feature which must be used with care. By unintentional mixing of directories you may easily end up with a inconsistent database, if the same backup is installed on more than one directory.
When this function is executed inside a transaction context
it returns
This function works exactly
Loads a series of definitions and data found in the
text file (generated with
Write locks are normally acquired on all nodes where a replica of the table resides (and is active). Read locks are acquired on one node (the local node if a local replica exists). Most of the context sensitive access functions acquire an implicit lock if they are invoked in a transaction context. The granularity of a lock may either be a single record or an entire table.
The normal usage is to call the function without checking
the return value since it exits if it fails and the
transaction is restarted by the transaction manager. It
returns all the locked nodes if a write lock is acquired, and
This function
Write locks are exclusive, which means that if one transaction manages to acquire a write lock on an item, no other transaction may acquire any kind of lock on the same item.
Read locks may be shared, which means that if one transaction manages to acquire a read lock on an item, other transactions may also acquire a read lock on the same item. However, if someone has a read lock no one can acquire a write lock at the same item. If some one has a write lock no one can acquire a read lock nor a write lock at the same item.
Conflicting lock requests are automatically queued if there
is no risk of a deadlock. Otherwise the transaction must be
aborted and executed again. Mnesia does this automatically
as long as the upper limit of maximum
For the sake of completeness sticky write locks will also be described here even if a sticky write lock is not supported by this particular function:
Sticky write locks are a mechanism which can be used to optimize write lock acquisition. If your application uses replicated tables mainly for fault tolerance (as opposed to read access optimization purpose), sticky locks may be the best option available.
When a sticky write lock is acquired, all nodes will be informed which node is locked. Subsequently, sticky lock requests from the same node will be performed as a local operation without any communication with other nodes. The sticky lock lingers on the node even after the transaction has ended. See the Mnesia User's Guide for more information.
Currently, two kinds of
This acquires a lock of type
This acquires a lock of type
Locks are released when the outermost transaction ends.
The semantics of this function is context sensitive. See
Invokes
This function takes a pattern with 'don't care' variables denoted as a '_' parameter. This function returns a list of records which matched the pattern. Since the second element of a record in a table is considered to be the key for the record, the performance of this function depends on whether this key is bound or not.
For example, the call
The function
The semantics of this function is context sensitive. See
Moves the copy of table
The storage type is preserved. For example, a RAM table moved from one node remains a RAM on the new node. It is still possible for other transactions to read and write in the table while it is being moved.
This function cannot be used on
This function makes it possible to traverse a table
and perform operations on all records in the table. When
the end of the table is reached, the special key
This function works exactly
Invokes
Invokes
This function reads all records from table
The semantics of this function is context sensitive. See
If the user wants to update the record it is more efficient to
use
Invokes
When tracing a system of Mnesia applications it is useful to be able to interleave Mnesia's own events with application related events that give information about the application context.
Whenever the application begins a
new and demanding Mnesia task, or if it is entering a new
interesting phase in its execution, it may be a good idea to
use
With this function, tables may be restored online from a
backup without restarting Mnesia.
The affected tables are write locked during the restoration, but regardless of the lock conflicts caused by this, the applications can continue to do their work while the restoration is being performed. The restoration is performed as one single transaction.
If the database is huge, it may not be possible to restore it online. In such cases, the old database must be restored by installing a fallback and then restart.
Invokes
Invokes
Invokes
Prints information about all table definitions on the tty.
Prints information about one table definition on the tty.
Matches the objects in the table
Note: for best performance
In its simplest forms the match_spec's look like this:
See the ERTS Users Guide and
For example to find the names of all male persons with an age over 30 in table Tab do:
MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
Guard = {'>', '$2', 30},
Result = '$1',
mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
Matches the objects in the table
Note: for best performance
Selects more objects with the match specification initiated
by
Note: Any modifying operations, i.e.
Changes the internal debug level of Mnesia. See the chapter about configuration parameters for details.
For each table Mnesia will determine its replica nodes
(
If the application detects that there has been a
communication failure (in a potentially partitioned network) which
may have caused an inconsistent database, it may use the
function
The master node setting is always local and it may be changed regardless of whether Mnesia is started or not.
The database may also become inconsistent if the
Removes the possibility for SNMP to manipulate the table.
Transforms an SNMP index to the corresponding Mnesia key. If the SNMP table has multiple keys, the key is a tuple of the key columns.
The
Makes it possible to read a row by its SNMP index. This index is specified as an SNMP OBJECT IDENTIFIER, a list of integers.
It is possible to establish a direct one to one mapping between Mnesia tables and SNMP tables. Many telecommunication applications are controlled and monitored by the SNMP protocol. This connection between Mnesia and SNMP makes it simple and convenient to achieve this.
The
mnesia:snmp_open_table(person, [{key, string}])
causes the
Consider the following schema for a table of company employees. Each employee is identified by department number and name. The other table column stores the telephone number:
mnesia:create_table(employee,
[{snmp, [{key, {integer, string}}]},
{attributes, record_info(fields, employees)}]),
The corresponding SNMP table would have three columns;
It is possible to have table columns that are not visible
through the SNMP protocol. These columns must be the last
columns of the table. In the previous example, the SNMP
table could have columns
In a table monitored by SNMP, all elements must be integers, strings, or lists of integers.
When a table is SNMP ordered, modifications are more expensive than usual, O(logN). And more memory is used.
Note:Only the lexicographical SNMP ordering is implemented in Mnesia, not the actual SNMP monitoring.
The start-up 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
participating nodes. Normally, each node has a directory where
all the Mnesia files are written. This directory will be
referred to as the Mnesia directory. Mnesia may also be
started on disc-less nodes. See
The set of nodes which makes up a Mnesia system is kept in
a schema and it is possible to add and remove Mnesia nodes
from the schema. The initial schema is normally created on
disc with the function
Each schema has a unique cookie which may be regarded as a unique schema identifier. The cookie must be the same on all nodes where Mnesia is supposed to run. See the Mnesia User's Guide for more information about these details.
The schema file, as well as all other files which Mnesia
needs, are kept in the Mnesia directory. The command line
option
Stops Mnesia locally on the current node.
Ensures that a copy of all events of type
Call the
This function waits until data have been committed and
logged to disk (if disk is used) on every involved node before
it returns, otherwise it behaves as
This functionality can be used to avoid that one process may overload a database on another node.
Returns information about the Mnesia system, such as transaction statistics, db_nodes, and configuration parameters. Valid keys are:
The list of Options may contain mnesia options or QLC
options, the following options are recognized by Mnesia:
The
This function executes the functional object
The code which executes inside the transaction
can consist of a series of table manipulation functions.
If something goes wrong inside the transaction as a result of a
user error or a certain table not being available, the
entire transaction is aborted and the function
If all is well,
A function which adds a family to the database can be
written as follows if we have a structure
add_family({family, F, M, Children}) ->
ChildOids = lists:map(fun oid/1, Children),
Trans = fun() ->
mnesia:write(F#person{children = ChildOids},
mnesia:write(M#person{children = ChildOids},
Write = fun(Child) -> mnesia:write(Child) end,
lists:foreach(Write, Children)
end,
mnesia:transaction(Trans).
oid(Rec) -> {element(1, Rec), element(2, Rec)}.
This code adds a set of people to the database. Running this code
within one transaction will ensure that either the whole
family is added to the database, or the whole transaction
aborts. For example, if the last child is badly formatted,
or the executing process terminates due to an
It is also useful to update the database within a transaction
if several processes concurrently update the same records.
For example, the function
raise(Name, Amount) ->
mnesia:transaction(fun() ->
case mnesia:wread({person, Name}) of
[P] ->
Salary = Amount + P#person.salary,
P2 = P#person{salary = Salary},
mnesia:write(P2);
_ ->
mnesia:abort("No such person")
end
end).
When this function executes within a transaction,
several processes running on different nodes can concurrently
execute the
Since Mnesia detects deadlocks, a transaction can be
restarted any number of times. This function will attempt a restart as specified in
This function applies the argument
Invokes
With this function it is possible to iterate over a backup, either for the purpose of transforming it into a new backup, or just reading it. The arguments are explained briefly below. See the Mnesia User's Guide for additional details.
Invokes
This function is used to de-install a fallback before it has been used to restore the database. This is normally a distributed operation that is either performed on all nodes with disc resident schema or none. Uninstallation of fallbacks requires Erlang to be up and running on all involved nodes, but it does not matter if Mnesia is running or not. Which nodes that are considered as disc-resident nodes is determined from the schema info in the local fallback.
Stops sending events of type
Some applications need to wait for certain tables to
be accessible in order to do useful work.
Invoke
Invoke
Writes the record
The function returns
The semantics of this function is context sensitive. See
Invokes
Mnesia reads the following application configuration parameters:
No trace outputs at all. This is the default setting.
Activates tracing of important debug events. These
debug events generate
Activates all events at the verbose level plus full
trace of all debug events. These debug events generate
Activates all events at the level debug. On this debug level, the Mnesia event handler starts subscribing to updates on all Mnesia tables. This level is only intended for debugging small toy systems since many large events may be generated.
An alias for none.
An alias for debug.
If
Mandatory disc. The schema is assumed to be located in the Mnesia directory. If the schema cannot be found, Mnesia refuses to start. This is the old behavior.
Mandatory RAM. The schema resides in RAM
only. At start-up, a tiny new schema is generated. This
default schema just contains the definition of the schema
table and only resides on the local node. Since no other
nodes are found in the default schema, the configuration
parameter
Optional disc. The schema may reside either on disc
or in RAM. If the schema is found on disc, Mnesia starts as a
disc based node and the storage type of the schema table is
First the SASL application parameters are checked, then the command line flags are checked, and finally, the default value is chosen.
mnesia_registry(3), mnesia_session(3), qlc(3), dets(3), ets(3), disk_log(3), application(3)