Skip to content

Mnesia backup and fallback is not working with mnesia #60

@Mikaka27

Description

@Mikaka27

Hi,

We're got this issue ticket: erlang/otp#8045
You can see that trying to run mnesia_rocksdb_fallback:run() produces error.

crasher:
initial call: mnesia_rocksdb:init/1
pid: <0.262.0>
registered_name: []
exception exit: {noproc,
{gen_server,call,
[mnesia_rocksdb_admin,
{rdb,{get_ref,t}},
infinity]}}
in function gen_server:call/3 (gen_server.erl, line 419)
in call from mnesia_rocksdb_admin:call/3 (src/mnesia_rocksdb_admin.erl, line 338)
in call from mnesia_rocksdb:init/1 (src/mnesia_rocksdb.erl, line 786)
in call from gen_server:init_it/2 (gen_server.erl, line 980)
in call from gen_server:init_it/6 (gen_server.erl, line 935)
ancestors: [mnesia_ext_sup,mnesia_sup,<0.243.0>]

Trying to fix that resulted in this PR:
erlang/otp#9152
What it does is it calls init_backend of all registered external backends during backup traversal (when we're restoring the tables from backup).
mnesia_rocksdb doesn't seem to like it, somehow it causes it to fail in a way that many of the backing files are missing (the main "CURRENT" file also).

I see the following ways forward:

  1. Mnesia does not call init_backend during backup traversal if there are no tables from this backend
    I've actually tried to do that, and it seems to make mnesia_rocksdb happy, but doesn't make mnesia_rocksdb_fallback:run() successful.
    It fails on ?m([], mnesia:dirty_match_object(t, {t,'_','_'})), on line 48. The cause is that during backup traversal after mnesia calls init_backend, it tries to delete external tables, and only later recreates them.
    This fails on mnesia_rocksdb because delete table is as follows:

    delete_table(Alias, Tab) ->
    case whereis_proc(Alias, Tab) of
        undefined ->
            ok;
        Pid when is_pid(Pid) ->
            call(Alias, Tab, delete_table)
    end.
    

    and we end up in a case where table holding process is undefined (because we didn't call load_table yet).
    The workaround would be to call load_table first and then clear it of all objects before restoring from backup, but I'm not happy with such workaround since mnesia_eleveldb allows to call delete_table without loading it first.

  2. mnesia_rocksdb must allow init_backend to be called during mnesia startup procedure and work fine after that

Either of those 2 would also require delete_table to work without loading it first.

Could you assist in moving this forward?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions