Most reliable way to create a mnesia table if it doesn’t exist

Best Practices for Creating a Mnesia Table if None Exists on Startup

Hi everyone,

we are currently working on an Erlang application that uses Mnesia for its embedded database, and I’m looking for the best way to handle table creation on startup when a table might not exist yet. I’ve explored a few potential solutions, but I’ve encountered some uncertainties and would appreciate insights from the community.

What I’ve Explored So Far:

  1. Using mnesia:table_info/2:

    • The idea here is to use mnesia:table_info(TableName, size) to check if the table exists. If the table doesn’t exist, the function is supposed to return {aborted, {no_exists, TableName}}. However, it’s unclear how reliable this method is, especially when dealing with tables that aren’t fully loaded yet.
  2. Checking with mnesia:system_info/1:

    • Another approach is to use mnesia:system_info(tables) to get a list of all known tables and check if the desired table is among them. This seems more straightforward but doesn’t address the potential issue of partially loaded tables.
  3. Using mnesia:wait_for_tables/2:

    • To ensure that the table is loaded, mnesia:wait_for_tables([TableName], Timeout) can be used. This is a good follow-up step after confirming the table’s existence, but it still depends on how the existence check is performed.
  4. Understanding mnesia_gvar:

    • We found that Mnesia uses an internal ETS table (mnesia_gvar) to store global variables, including table properties. Functions like mnesia_schema:get_table_properties/1 interact with this table. However, the exact mechanics of when and how mnesia_gvar is populated are not entirely clear, making it hard to rely on this knowledge for table creation checks.

What I Need Help With:

Given the above explorations, I’m looking for the best practice to:

  • Check if a Mnesia table exists on startup.
  • Create the table if it doesn’t exist.

I want to ensure that the approach is reliable and handles all edge cases, including tables that might not be fully loaded. What are the recommended strategies for this scenario? Is there a more straightforward or reliable method that I might have overlooked?

Thanks in advance for your help!

Call mnesia:wait_for_tables(schema, Timeout) before any other mnesia operations.

2 Likes

All the methods you suggest draw on metadata which is all updated when a table creation transaction is committed. But as Vance suggests, it’s important to ensure that the schema has been fully loaded first.

Especially if you have multiple nodes individually performing this check, you might want to use mnesia_schema:schema_transaction/1 and mnesia_schema:do_create_table/1. These aren’t documented, so may take a little getting used to.

A very old example exists in the Jungerl (rdbms):

Note the use of mnesia_schema:list2cs/1 to convert a proplist to a cstruct, and that the table name needs to be included in the proplist.

3 Likes