MNESIA

Mnesia is a database management system (DBMS) that comes with Erlang. It uses the Erlang Term Storage and DETS underneath, but provides many more features than those components.

Creating the initial Database

During the course of creating this database, you’ll do the following:

  1. Create a Schema

          mnesia:create_schema([node()])
    
  2. Initialize MNESIA

          mnesia:start()
    
  3. Create the DB Tables

          mnesia:create_table(record_name, [{attributes, record_info(fields, record_name)}])
    
  4. Populate Tables

By default, Mnesia will store your table in RAM only (ram_copies) on the current node. This is speedy, but it means the data vanishes if the node crashes. If you specify disc_copies (note the spelling), Mnesia will keep a copy of the database on disk, but still use RAM for speed. You can also specify disc_only_copies, which will be slow. (…) . By combining these options and (eventually) multiple nodes, you should be able to create fast and resilient systems. (Laurent 2017, 152)

Your interactions with Mnesia should be contained in transactions, especially when your database is shared across multiple nodes. The main mnesia:write, mnesia:read, and mnesia:delete methods work only within transactions, period. (Laurent 2017, 155)

Queries

  • Selecting All Data in a Table:
  %% sql equivalent
  %% select * from <table>
  select_all(from) -> do(qlc:q([x || x <- mnesia:table(from)]));
  • Joins

Transactions

This is exactly the guarantee that mnesia:transaction/1 provides. Either all the reads and writes to the tables in the database within a particular transaction succeed, or none of them does. If none of them does, the transaction is said to fail. If the transaction fails, no changes will be made to the database.

The strategy that Mnesia uses for this is a form of pessimistic locking. Whenever the Mnesia transaction manager accesses a table, it tries to lock the record or the entire table depending upon the context. If it detects that this might lead to deadlock, it immediately aborts the transaction and undoes any changes it has made. (Armstrong 2013, 327)

something(...) ->
  F = fun() ->
    % To add a Row
    mnesia:write(Row)
    % or delete it
    mnesia:delete(Oid)
    % ... or ...
    qlc:e(Q)
    end,
  mnesia:transaction(F).

References:

Armstrong, Joe. 2013. “Programming Erlang: Software for a Concurrent World.”
Laurent, Simon St. 2017. Introducing Erlang: Getting Started in Functional Programming. O’Reilly Media, Inc.

Backlinks: