我有一组erlang节点通过Mnesia的“extra_db_nodes”复制他们的数据......我需要升级硬件和软件,所以当我从节点到节点时,我必须分离一些节点。
如何删除节点并仍保留已插入的数据?
[更新]删除节点与添加节点一样重要。随着集群的增长,它也必须收缩。如果没有,那么Mnesia将忙于尝试向不存在的节点发送数据,以填满队列并保持网络繁忙。
在完成erlang / mnesia源代码之后,[最终更新]我能够确定无法完全取消关联节点。虽然del_table_copy删除了表之间的链接,但它不完整。我会关闭这个问题,但没有一个密切的描述是足够的。
答案 0 :(得分:6)
我希望我很久以前就找到了这个:http://weblambdazero.blogspot.com/2008/08/erlang-tips-and-tricks-mnesia.html
基本上,有一个功能正常的集群......
登录要删除的群集
停止mnesia
mnesia:stop().
登录群集上的其他节点
删除架构
mnesia:del_table_copy(schema, node@host.domain).
答案 1 :(得分:3)
我参加派对的时间非常晚,但在寻找同一问题的解决方案时,在文档中遇到了这些信息:
“函数调用 Mnesia的:del_table_copy(架构, mynode @ host)删除节点 来自Mnesia系统的'mynode @ host'。 如果mnesia正在运行,则调用失败 'MYNODE @主机'。其他的mnesia节点 永远不会尝试连接到该节点 再次。请注意,如果有光盘 节点上的驻留架构 'mynode @ host',整个mnesia 目录应该删除。这个可以 用mnesia完成:delete_schema / 1。 如果mnesia再次启动了 节点'mynode @ host'和目录 没有被清除,mnesia的 行为未定义。“ (http://www.erlang.org/doc/apps/mnesia/Mnesia_chap5.html#id74278)
我认为以下可能符合您的要求:
AllTables = mnesia:system_info(tables),
DataTables = lists:filter(fun(Table) -> Table =/= schema end,
AllTables),
RemoveTableCopy = fun(Table,Node) ->
Nodes = mnesia:table_info(Table,ram_copies) ++
mnesia:table_info(Table,disc_copies) ++
mnesia:table_info(Table,disc_only_copies),
case lists:member(Node,Nodes) of
true -> mnesia:del_table_copy(Table,Node);
false -> ok
end
end,
[RemoveTableCopy(Tbl,'gone@gone_host') || Tbl <- DataTables].
rpc:call('gone@gone_host',mnesia,stop,[]),
rpc:call('gone@gone_host',mnesia,delete_schema,[SchemaDir]),
RemoveTablecopy(schema,'gone@gone_host').
虽然,我没有测试过,因为我的情况略有不同。
答案 2 :(得分:1)
我当然使用此方法执行此操作(支持mnesia:del_table_copy / 2使用)。请参阅下面的removeNode / 1:
-module(tool_bootstrap).
-export([bootstrapNewNode/1, closedownNode/0,
finalBootstrap/0, removeNode/1]).
-include_lib("records.hrl").
-include_lib("stdlib/include/qlc.hrl").
bootstrapNewNode(Node) ->
%% Make the given node part of the family and start the cloud on it
mnesia:change_config(extra_db_nodes, [Node]),
%% Now make the other node set things up
rpc:call(Node, tool_bootstrap, finalBootstrap, []).
removeNode(Node) ->
rpc:call(Node, tool_bootstrap, closedownNode, []),
mnesia:del_table_copy(schema, Node).
finalBootstrap() ->
%% Code removed to actually copy over my tables etc...
application:start(cloud).
closedownNode() ->
application:stop(cloud), mnesia:stop().
答案 3 :(得分:0)
如果您已将表(已添加的表副本)复制到您要删除的节点以外的节点上,那么您已经很好了 - 只需删除该节点即可。
如果您想稍微整洁,可以先从mnesia:del_table_copy/2
删除要删除的节点中的表格副本。
通常,mnesia会优雅地处理节点丢失并检测节点重新加入(重新启动的节点从保持运行的节点获取新的表副本,未重新启动的节点被检测为网络分区事件)。 Mnesia不会为已关闭的节点消耗CPU或网络流量。我想,虽然我没有在源代码中确认它,但mnesia不会重新连接到自动关闭的节点 - 预计会关闭的节点重启(mnesia)并重新连接。
mnesia:add_table_copy/3
,mnesia:move_table_copy/3
和mnesia:del_table_copy/2
是您应该查看的实时架构管理功能。
extra_db_nodes
参数仅在初始化新数据库节点时使用 - 一旦新节点具有模式副本,则不需要extra_db_nodes
参数。