10

我有一组 erlang 节点,它们通过 Mnesia 的“extra_db_nodes”复制它们的数据......我需要升级硬件和软件,所以当我从一个节点到另一个节点时,我必须分离一些节点。

如何删除一个节点并仍然保留插入的数据?

[更新] 删除节点与添加节点一样重要。随着时间的推移,随着集群的增长,它也必须收缩。如果没有,那么 Mnesia 将忙于尝试将数据发送到不存在的节点并填满队列并保持网络繁忙。

[最终更新] 在翻阅 erlang/mnesia 源代码后,我能够确定无法完全分离节点。虽然 del_table_copy 删除了表之间的链接,但它是不完整的。我会结束这个问题,但没有一个密切的描述是充分的。

4

4 回答 4

6

我希望我很久以前就发现了这个:http ://weblambdazero.blogspot.com/2008/08/erlang-tips-and-tricks-mnesia.html

基本上,使用正常运行的集群....

  • 登录要移除的集群

  • 停止健忘症

    mnesia:stop().
    
  • 登录到集群上的不同节点

  • 删除架构

    mnesia:del_table_copy(schema, node@host.domain).
    
于 2012-10-05T03:06:06.443 回答
3

我参加聚会的时间非常晚,但是在寻找解决同一问题的方法时,在文档中发现了以下信息:

“函数调用 mnesia:del_table_copy(schema, mynode@host) 从 Mnesia 系统中删除节点 'mynode@host'。如果 mnesia 在 'mynode@host' 上运行,则调用失败。其他 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').

不过,我没有测试它,因为我的情况略有不同。

于 2011-01-19T23:57:08.037 回答
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().
于 2009-06-08T23:11:06.880 回答
0

如果您在要删除的节点之外的节点上复制了表(添加的表副本),那么您已经很好 - 只需删除节点即可。

如果你想稍微整洁一点,你可以从你要删除的节点中删除表副本,首先通过mnesia:del_table_copy/2.

通常,mnesia 会优雅地处理节点丢失并检测节点重新加入(重新启动的节点从继续运行的节点获取新的表副本,未重新启动的节点被检测为网络分区事件)。Mnesia 不会为已关闭的节点消耗 CPU 或网络流量。我认为,虽然我没有在源代码中确认它,但 mnesia 不会重新连接到自动关闭的节点 - 关闭的节点预计会重新启动(mnesia)并重新连接。

mnesia:add_table_copy/3mnesia:move_table_copy/3并且mnesia:del_table_copy/2是您应该查看实时模式管理的功能。

extra_db_nodes参数仅应在初始化新的 DB 节点时使用 - 一旦新节点具有模式的副本,它就不需要该extra_db_nodes参数。

于 2009-06-03T22:06:10.993 回答