February 27, 2021
Hot Topics:

Mnesia: A Distributed DBMS Rooted in Concurrency

  • By Roberto Giorgetti
  • Send Email »
  • More Articles »

Mnesia is a complete database management system (DBMS) included in Erlang OTP, an open source development environment for concurrent programming based on the Erlang language. As Mnesia is a true DBMS, distributing, replicating and fragmenting your data with it—even among thousands of nodes around the world—is child's play. You only need to run different Erlang nodes where you want to distribute the Mnesia database.

The story of how Mnesia got its name is probably apocryphal, but legend has it that the original name was Amnesia until an Ericsson executive declared that a database couldn't be called something associated with forgetting. So, the engineers dropped the "A" and built Mnesia, something that remembers all. Mnesia offers the fault tolerance feature of any program implemented in Erlang, and you can interact with the database in Erlang itself. With Mnesia, Erlang becomes a database language.

In this article, I highlight some of Mnesia's important features. The file test.erl provided in the source code download contains some simple functions that group together a few lines of code. It mainly uses an Erlang shell.

Unless absolutely necessary, I do not explain all the aspects of Erlang syntax or basic concepts. You can easily find information about those in the online documentation. Pay particular attention to atoms, variables, tuples, and lists. You can even find useful background information in my DevX article "Writing Parallel Programs with Erlang," where I explore the concurrent aspects of the language.

Nodes: The Heart of Erlang

The concept of nodes is at the heart of Erlang. Every Erlang shell could be a node, provided that it is started with a name and a secret word called a cookie. Let's see Erlang in action with some examples. I have three Debian Linux machines on my LAN (charlie, delta and nemo) where I have installed Erlang by simply running:

apt-get install erlang

I choose a nonsensical string (AXHMTYGVJDNJIFGYADNJ) as the secret word and first, second and third as the node names. Then, I ran these two commands on charlie and delta:

erl -sname first -setcookie AXHMTYGVJDNJIFGYADNJ
erl -sname second -setcookie AXHMTYGVJDNJIFGYADNJ

I can now connect the two Erlang nodes, first@charlie and second@delta, with a single ping from charlie:

(first@charlie)1> net_adm:ping(second@delta).                            

I can test the connection by asking which nodes are connected:

(first@charlie)2> nodes().

As you can see, I already have two cooperative Erlang nodes that can easily communicate with each other.

Mnesia Schema

The test.erl file in the source code download contains two functions, test:start_schema(NodesList) and test:start_tables, that have to be run only once. They deal with creating Mnesia schema, defining tables, and initially populating those tables with initial data.

The first operation you need to complete is creating a Mnesia schema, even before you start any Mnesia engine on the connected nodes. A Mnesia schema is a special table and a local directory on the filesystem. This directory can contain several files and must be unique for each node. You create the schema once for each database under the current directory with the name Mnesia.node_name@host, but you can override the default with the erl command option -mnesia dir [database_dir].

The function mnesia:create_schema(NodesList) takes a list of already connected Erlang nodes as arguments. If you run the following from one of the connected nodes:


the Mnesia dir will exist only in the local node. But if you run this:


all the nodes in the list will have a copy of Mnesia schema and the system will keep all the copies synchronized. This is an important detail with regard to redundancy and failover issues.

To put this in practice, I distribute the file test.erl on my three nodes and compile it with this command:


To create a schema on both the nodes first@charlie and second@delta, I run the following from one of the two nodes:


Then I launch mnesia:start() on the other one.

Mnesia Tables

The database tables definition is another one-time operation, which you can perform on one of the nodes that have a copy of the schema. With the mnesia:create_table function, you can design the structure of the table as well as set a lot of important table attributes. I create and populate table1 and table2 by running:

(first@charlie)3> test:start_tables().
=INFO REPORT==== 4-Jan-2010::16:22:27 ===
    application: mnesia
    exited: stopped
    type: temporary

Provided that the file test.erl also had been compiled on second@delta, I could run the above functions also on delta. Take a look at the following code to see how the previously cited function mnesia:create_table is used:

    {type, set},
    {attributes, record_info(fields, table1)},
    {disc_copies, [first@charlie, second@delta]}  

As you can see, the function takes as arguments a list of tuples {key, value} that determine the table characteristics. In this case, I create a "set" table named table1 whose columns are defined in the record directive at the top of the file:

-record(table1, {table1_id, name, color, number}).

Note the disc_copies key, which specifies where a hard disk copy of the table will exist. This means that you can tune the redundancy of a Mnesia database at the table level. In this case, table1 has copies on the hard disk on the nodes first@charlie and second@delta. In the next section, I show this function in action.

Page 1 of 2

This article was originally published on February 11, 2010

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date