问题描述
警告:背景信息很长。如果您认为您需要背景信息之前的问题,请跳到底部。感谢这将要花费的时间!
我已经遍布网络(阅读谷歌),我没有找到一个很好的答案。是的,在erlang.org网站上有很多链接和参考Mnesia文档,但即使这些链接也受到版本的限制。
所以在最简单的情况下,当前连接到的node()与表的所有者相同,那么备份/恢复将会起作用。例如:
$ erl -sname mydatabase
>函数mnesia:start()方法。
> Mnesia的:create_schema(...)。
> Mnesia的:CREATE_TABLE(...)。
> Mnesia的:备份( / 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}]])。
当然这也很简单。现在这里是棘手的东西....
- 让我们说你正在采取每日备份。而且你的数据库服务器死机,你被迫更换硬件。如果要按原样还原数据库,则需要使用与之前相同的名称命名新硬件,并且还需要将节点命名为相同。
- 如果您要更改硬件和/或node()...的名称,或者要在其他机器上还原,则需要执行node_change进程。 (和mnesia文档) / li>
但这里是一些复杂的事情。虽然我的熟人,谁是erlang和mnesia专家建议,mnesia的复制是严重的缺陷,你不应该使用它(目前还没有任何替代品,我知道,什么是你将要实现更好的版本的机会;不是可能)
所以你有两个节点()正在复制ram和基于盘的表。您一直使用默认的BackupMod维护使用标准备份定期备份数据库的策略。有一天,经理要求您验证备份。只有当您尝试恢复数据库时,才能得到:
{atomic,[]}
根据文档,这意味着没有错误...但没有恢复任何表。
不想运行change_node过程,您记得node()和hostname必须匹配,以便您更改主机名和-sname参数以匹配数据的机器被支持这个时候你会得到一个奇怪的错误:
{aborted,{'EXIT',{aborted,{bad_commit,{missing_lock, mydatabase @ otherhost}}}}}
仍然不想运行change_node过程我快速克隆恢复我的服务器让我有两台类似的机器。我可以适当地命名以匹配生产服务器。我开始恢复过程。找到了!我现在在恢复服务器上有真实的工作数据。
我想说这是路的尽头,但是我没有问过一个问题但是呢,那么这个点啊...所以这里是吗?
QUESTION:如果我想恢复被采取的备份从一组复制的mnesia节点,如何修改文件(类似于change_node过程),以便其他节点被忽略或从备份中删除?
问题略有不同:如何在单个节点()上恢复复制多节点()mnesia数据库?
我认为这个问题属于与简单的Mnesia问题相关的更广泛的类别:
The first and simplest solution, if your db is not huge, is to use the mnesia:traverse_backup function (see Mnesia User guide).Following is an example from the Mnesia User 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).
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).
The most important part here is the manipulation of the {schema, db_nodes, Nodes}
tuple which let you rename or replace the db nodes.
BTW, I've used that function in the past and one thing I noticed is that the backup terms format changes between mnesia versions, but maybe it was simply me writing bad code. Just print a backup log for a small mnesia database to check backup term format, if you wanna be sure.
Hope this helps!
这篇关于什么是备份/恢复mnesia数据库的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!