代码之家  ›  专栏  ›  技术社区  ›  Richard

如何删除额外节点

  •  10
  • Richard  · 技术社区  · 16 年前

    我有一组Erlang节点正在通过mnesia的“额外的”db_节点复制它们的数据…我需要升级硬件和软件,所以在我从一个节点到另一个节点的过程中,我必须分离一些节点。

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

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

    [ 最后更新 ]在遍历erlang/mnesia源代码之后,我可以确定不可能完全取消节点的关联。当del_table_copy删除表之间的链接时,它是不完整的。我想结束这个问题,但没有一个详细的描述是充分的。

    4 回复  |  直到 6 年前
        1
  •  5
  •   James Kingsbery    11 年前

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

    基本上,有了一个正常工作的集群……

    • 登录到要删除的群集

    • 停止记忆

      mnesia:stop().
      
    • 登录到群集中的其他节点

    • 删除架构

      mnesia:del_table_copy(schema, node@host.domain).
      
        2
  •  3
  •   Shamis Shukoor    6 年前

    我参加聚会非常晚,但在寻找解决同一问题的方法时,我在医生那里看到了这个信息:

    “函数调用 mnesia:del_table_copy(模式, mynode@host)删除节点 来自mnesia系统的“mynode@host”。 如果mnesia正在运行,则调用失败 “MyNodo@主机”。其他记忆节点 从不尝试连接到该节点 再一次。注意,如果有光盘 节点上的驻留架构 “mynode@host”,整个记忆空间 应删除目录。这个罐头 使用mnesia:删除_模式/1。 如果在 节点“mynode@host”和目录 尚未清除,记忆障碍 行为未定义。” ( 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').
    

    不过,我还没有测试它,因为我的场景略有不同。

        3
  •  1
  •   Alan Moore    16 年前

    我确实使用了这个方法来执行这个操作(支持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().
    
        4
  •  0
  •   archaelus    16 年前

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

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

    通常,mnesia会优雅地处理节点丢失并检测节点重新加入(重新启动的节点从保持运行的节点获取新的表副本,未重新启动的节点被检测为网络分区事件)。对于已停机的节点,记忆空间不消耗CPU或网络流量。我想,虽然我还没有在源代码中确认它,但mnesia不会重新连接到自动关闭的节点-关闭的节点应该重新启动(mnesia)并重新连接。

    mnesia:add_table_copy/3 , mnesia:move_table_copy/3 记忆障碍:del_table_copy/2 是您应该查看的用于实时模式管理的函数。

    这个 extra_db_nodes 仅当初始化新的DB节点时才应使用参数-一旦新节点具有架构的副本,它就不需要 外节点 参数。