:mnesia - error (:aborted / :no_exist) when setting table to disk_copies

So just for fun I’m playing around with :mnesia - before using libraries like Mnesiac or Amnesia I wanted to explore the the Erlang core. So far it is really awesome, very easy to set up and even easier to use. The Erlang documentation is great, too, and can be used perfectly fine in Elixir.
However, I have one (I guess tiny) problem, that I could not manage to solve so far, and that is setting up :mnesia with disk_copies, which means I guess that :mnesia uses dets instead of ets in the background.

So first of all, I created a supervised project with mix, and added :mnesia like this:

  def application do
    [
      extra_applications: [:logger],
      included_applications: [:mnesia],
      mod: {TestDb.Application, []}
    ]
  end

So I put it under included_applications so it does not get started automatically, because we need to set up the scheme before.

I also created a config.exs file to name the data directory:

import Config
config :mnesia, dir: 'mnesia/'

The Application itself starts a GenServer like this (I only paste the relevant parts, so no start_link etc.):

 alias :mnesia, as: Mnesia

  def init(state) do
    setup_mnesia()
    {:ok, state}
  end

  defp setup_mnesia do
    Mnesia.create_schema([node()])
    Mnesia.start()

    Mnesia.create_table(:testtable, [
      {:disk_copies, [node()]},
      {:type, :set},
      {:attributes, [:id, :testdata]}
    ])
  end

Whenever I run this in iex:

:mnesia.transaction(fn -> :mnesia.read(:testtable, "123") end)
I get the error
{:aborted, {:no_exists, :testtable}}
However, I I do the same, when setting the table to :ram_copies instead of :disk_copies, I get this:
{:atomic, []}
I get the same error for writing of course. like with this command:
:mnesia.transaction(fn -> :mnesia.write({:testtable, "123", ["foobar"]}) end)

Also interesting to see, if I run :mnesia.info()

use fallback at restart = false
running db nodes   = [nonode@nohost]
stopped db nodes   = [] 
master node tables = []
remote             = []
ram_copies         = []
disc_copies        = [schema]
disc_only_copies   = []
[{nonode@nohost,disc_copies}] = [schema]
2 transactions committed, 3 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []

The :testtable is listed nowhere, which makes sense since the that what the error message says. When using :ram_copies, the table is listed there.

Also: the data directory is actually created, so at least the config.exs file setting works.

However, I wonder: what am I missing? Do I have to initialize the table somehow when using :disk_copies? I Guess it is just a minor thing, but in the docs and tutorials I found and read, I could not find the answer.

Thank you in advance!

1 Like

I found the solution: my Mnesia.create_table seems to have wrong argument structure. This is the right way:

Mnesia.create_table(:testtable, attributes: [:id, :testdata], disc_copies: [node()], type: :set)   
1 Like