如何删除额外的节点

时间:2009-05-04 12:42:13

标签: erlang mnesia

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

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

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

在完成erlang / mnesia源代码之后,

[最终更新]我能够确定无法完全取消关联节点。虽然del_table_copy删除了表之间的链接,但它不完整。我会关闭这个问题,但没有一个密切的描述是足够的。

4 个答案:

答案 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/3mnesia:move_table_copy/3mnesia:del_table_copy/2是您应该查看的实时架构管理功能。

extra_db_nodes参数仅在初始化新数据库节点时使用 - 一旦新节点具有模式副本,则不需要extra_db_nodes参数。