警告:背景信息是相当长的。 跳到底部,如果你认为你需要之前的背景信息的问题。 升值的时候,这是要带!
我一直都在网上(读谷歌),我还没有找到一个很好的答案。 是的,有很多的链接和参考对erlang.org网站,但Mnesia的文档,即使这些链接从版本炎困扰。
所以,在节点()当前连接到相同的备份/恢复是去工作,然后设置表的所有者最简单的情况。 例如:
$ erl -sname mydatabase
> mnesia:start().
> mnesia:create_schema(...).
> mnesia:create_table(...).
> mnesia:backup("/tmp/backup.bup").
> mnesia:restore("/tmp/backup.bup", [{default_op, recreate_tables}]).
嘿,这伟大的工程!
但是,如果数据库实际上是一个远程节点()或远程节点()上的远程对接上运行,那么你必须启动备份是这样的:
$ erl -sname mydbadmin
> rpc:call(mydatabase@host, mnesia, backup, ["/tmp/backup.bup"]).
> rpc:call(mydatabase@host, mnesia, restore, ["/tmp/backup.bup", [{default_op, recreate_tables}]]).
当然,这是很简单。 现在,这里是棘手的事情....
- 比方说,你正在服用每日备份。 而你的Mnesia数据库服务器死了,你是被迫更换硬件。 如果你想恢复DB原样,那么你需要命名与它以前有相同名称的新硬件,你也需要命名的节点相同。
- 如果你想改变硬件和/或节点(的名称)...或者你想在不同的机器上恢复,那么你就需要去通过node_change过程。 (描述在这里和在Mnesia的文档)
但这里情况变得有些复杂。 而我的熟人,谁是Erlang和Mnesia的专家建议,Mnesia的复制是严重错误的,你不应该使用它(目前有没有办法,我知道的,什么是你要实现更好的版本的机会;不可能)
所以,你有两个节点()被复制RAM和盘基表。 你一直保持使用默认BackupMod与标准备份定期备份数据库的政策。 有一天,经理要求您验证备份。 只有当你试图恢复你的数据库:
{atomic,[]}
并根据文件,这意味着没有错误...,但没有表被恢复。
不想跑你记住,节点()和主机名必须匹配,以便您更改主机名和-sname参数去那里数据被备份的计算机匹配change_node程序。 而这一次你会得到一个奇怪的错误:
{aborted,{'EXIT',{aborted,{bad_commit,{missing_lock,mydatabase@otherhost}}}}}
还没想运行change_node过程我很快恢复克隆我的服务器,这样我有两个类似的机器。 我的名字,然后适当地匹配生产服务器。 我开始恢复过程。 找到了! 我现在恢复服务器上的实际工作数据。
我想说,这是路的尽头......但我还没有问一个问题还没有和这么点....所以在这里它是什么?
问:如果我要恢复这是从复制的Mnesia节点的集群拍摄,我怎么修改文件(类似于change_node程序),从而使其它节点忽略或从备份删除备份?
问略有不同:如何还原复制的多节点()Mnesia的数据库中的单个节点上()?
Answer 1:
我认为这个问题属于在所涉及到一个简单的Mnesia的问题更广泛的类别:
如何重新命名一个Mnesia节点?
第一,简单的解决方案,如果你的数据库不是很大,就是用函数mnesia:traverse_backup功能(见Mnesia的用户指南 )。 以下是从Mnesia的用户指南的示例:
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).
view(Source, Mod) ->
View = fun(Item, Acc) ->
io:format("~p.~n",[Item]),
{[Item], Acc + 1}
end,
mnesia:traverse_backup(Source, Mod, dummy, read_only, View, 0).
这里最重要的部分是操纵{schema, db_nodes, Nodes}
元组这让你重新命名或更换数据库节点。
顺便说一句,我使用该功能在过去,有一两件事我注意到的是Mnesia的版本之间的备份格式条款的变化,但也许它就是被我写不好的代码。 只是打印备份日志小Mnesia的数据库来检查备份项的格式,如果你想成为肯定。
希望这可以帮助!
Answer 2:
我有一个非常很难得到这个工作,所以我将分享我所经历的步骤。
通过备份中要恢复(单个节点)分布式系统中的节点开始:
> mnesia:backup("/path/to/backup").
请确保以下适应change_node_name
可你要还原到的节点上:
-module(move_backup).
-export([set_node_name/4]).
set_node_name(From, To, Source, Target) ->
Switch =
fun (Nodes) ->
case lists:member(From, Nodes) of
true -> [To];
false -> []
end
end,
Convert =
fun({schema, db_nodes, Nodes}, Acc) ->
{[{schema, db_nodes, 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, Switch(Val)};
false-> {Key, Val}
end
end,
{[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc};
(Other, Acc) ->
{[Other], Acc}
end,
mnesia:traverse_backup(Source, Target, Convert, switched).
转换备份:
> move_backup:set_node_name('before@host', 'after@host', "/path/to/backup", "/path_to_backup_converted").
我要去假设新节点完全是空的(如果不是这种情况下,你可能想改变default_op
参数)。 有两种选择,一个是现场还原:
> mnesia:restore("/path/to/backup_converted", [{default_op, recreate_tables}]).
这是伟大的,但如果你有一个大的数据库可能会使用大量内存(我的是10GB〜所以这导致了内存溢出异常)。 另一种方法是安装一个备用,并重新启动你的shell:
> mnesia:install_fallback("/path/to/backup_converted").
> q().
然后当你重新启动外壳程序(假设你使用正确的节点名),它会导入完整的数据库。
文章来源: what is the proper way to backup/restore a mnesia database?