Search code examples
erlangmnesia

How to rename the Node running a mnesia Database


I created a Mnesia database / Schema on machine1. The node was named mypl@machine1. I then moved all files to machine2, because machine1 broke down. Everything runs fine as long as the code is running with the name "mypl@machine1". Obviously this is somewhat confugsing, because it is now running on machine2.

If I start Erlang with the node name "mypl@machine2" the Mnesia Database appears being empty.

How do I rename the node in a Mnesia Database from machine1 to machine2?


Solution

  • I don't think this can be done online on a single node(anyone?), but it is possible to do via a backup/restore in addition to running two nodes and adding table copies. In the Mnesia User's guide section 6.9.1 you'll find some code that uses mnesia:traverse_backup to alter the node names in the schema table (Shown below) in an mnesia backup file. The module name you should probably use is mnesia_backup.

    With this code you'll need to:

    %% On mypl@machine1
    mnesia:backup("/path/to/mnesia.backup").
    change_node_name(mnesia_backup, mypl@machine1, mypl@machine2,
                     "/path/to/mnesia.backup", "/path/to/new.mnesia.backup").
    %% On mypl@machine2
    mnesia:restore("/path/to/new.mnesia.backup", []).
    

    I'm not sure if you need to create the schema first on mypl@machine2.

    The change node name code from the user's guide:

    change_node_name(Mod, From, To, Source, Target) ->
        Switch =
            fun(Node) when Node == From -> To;
               (Node) when Node == To -> throw({error, already_exists});
               (Node) -> Node
            end,
        Convert =
            fun({schema, db_nodes, Nodes}, Acc) ->
                    {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc};
               ({schema, version, Version}, Acc) ->
                    {[{schema, version, Version}], Acc};
               ({schema, cookie, Cookie}, Acc) ->
                    {[{schema, cookie, Cookie}], Acc};
               ({schema, Tab, CreateList}, Acc) ->
                    Keys = [ram_copies, disc_copies, disc_only_copies],
                    OptSwitch =
                        fun({Key, Val}) ->
                                case lists:member(Key, Keys) of
                                    true -> {Key, lists:map(Switch, Val)};
                                    false-> {Key, Val}
                                end
                        end,
                    {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc};
               (Other, Acc) ->
                    {[Other], Acc}
            end,
        mnesia:traverse_backup(Source, Mod, Target, Mod, Convert, switched).