Search code examples
erlangmnesia

how to backup/restore only single table from/to mnesia?


I have some big tables with disc_only_copies type. Now I need change short node name to long but cannot do it with RAM limitation...

Can I use backup/restore database partly (table by table)?


Solution

  •     -module(test).
        -compile(export_all).
    
        -record(tab, {first, second}).
    
        do() ->
                mnesia:create_schema([node()]),
                mnesia:start(),
                mnesia:create_table(tab, [{disc_copies, [node()]}, {attributes, record_info(fields, tab)}]),
                mnesia:dirty_write({tab, 1, 2}),
                mnesia:dirty_write({tab, a, b}),
                mnesia:stop().
    
        change_node('extra@localhost') ->
                'extra@example.com';
        change_node('ejabberd@localhost') ->
                'ejabberd@example.com';
        change_node(Node) ->
                Node.
    
        handle_nodes(Nodes) ->
                lists:map(fun(Node) ->
                        change_node(Node)
                end, Nodes -- [one@badhost, extra@badhost]).
    
        handle_cookie({TS, Node}) ->
                {TS, change_node(Node)}.
    
        handle_version_value([]) ->
                [];
        handle_version_value({'one@badhost', _}) ->
                [];
        handle_version_value({'extra@badhost', _}) ->
                [];
        handle_version_value({Node, TS}) ->
                {change_node(Node), TS}.
    
        handle_version({Key, Value}) ->
                {Key, handle_version_value(Value)}.
    
        handle_def(Def) ->
                lists:map(fun({Key, Value} = Property) ->
                        case Key of
                        ram_copies ->
                                {Key, handle_nodes(Value)};
                        disc_copies ->
                                {Key, handle_nodes(Value)};
                        disc_only_copies ->
                                {Key, handle_nodes(Value)};
                        cookie ->
                                {Key, handle_cookie(Value)};
                        version ->
                                {Key, handle_version(Value)};
                        _ ->
                                Property
                        end
    
            end, Def).
    
    go() ->
            {ok, N} = dets:open_file(schema, [{file, "./schema.DAT"},{repair,false}, {keypos, 2}]),
            do2(N),
            dets:sync(N),
            dets:close(N).
    
    do2(N) ->
            do2(N, dets:first(N)).
    
    do2(_N, '$end_of_table') ->
            ok;
    do2(N, Key) ->
            io:format("process: ~p~n", [Key]),
            [{N, Tab, Def}] = dets:lookup(N, Key),
            NewDef = handle_def(Def),
            dets:insert(N, {N, Tab, NewDef}),
    %       file:write_file("schema.txt", io_lib:format("~p~n", [{N, Tab, NewDef}]), [append]),
            do2(N, dets:next(N, Key)).