【问题标题】:Remove running node from mnesia cluster从 mnesia 集群中删除正在运行的节点
【发布时间】:2014-09-10 19:18:07
【问题描述】:

我需要从 mnesia 集群中删除一个正在运行的节点。这是一个需要执行一些维护的合法节点。但是,我们希望保持此节点运行并为请求提供服务。我找到了this 的帖子。这有助于将其从其他节点中删除。但是,一旦在孤立节点上重新启动 mnesia,它就会返回到集群中的其他节点。

从每个非孤立节点,我运行一个执行以下操作的脚本:

    rpc:call('node_to_be_orphaned', mnesia, stop, []),
    mnesia:del_table_copy(schema, 'node_to_be_orphaned'),

^^ 此时 mnesia:system_info(db_nodes) 表明该节点确实已被移除。

    rpc:call('node_to_be_orphaned', mnesia, start, []),

现在它回来了。啊!

所以,我然后尝试翻转它并从孤儿中删除其他节点,首先添加以下内容。

    rpc:call(ThisNode, mnesia, stop, []),
    rpc:call('node_to_be_orphaned', mnesia, del_table_copy, [schema, node()]),
    rpc:call(ThisNode, mnesia, start, []),

这只是创建一个没有区别的循环。

有没有办法让一个节点脱离 mnesia 集群,同时让它保持正常运行?

非常感谢任何和所有指导

【问题讨论】:

  • 您是否尝试在重新启动之前从 system.config 中删除集群配置?
  • 尝试让孤儿节点在删除表副本后删除其架构目录的内容。不确定这是否有效,但我以前曾目睹过这种行为,我认为这就是我为解决它所做的。肮脏的黑客,如果它有效的话。

标签: erlang mnesia


【解决方案1】:

架构是困扰您的问题。您可以添加节点,但在保留表副本的同时删除它们是错误的,很困难。这是当节点连接到分布式模式时发生的情况,除了接收新模式:

将节点添加到复制模式的节点列表中 影响两件事。首先,它允许将其他表复制到 这个节点。其次会导致Mnesia尝试联系节点 启动全盘节点

这就是the documentation 所说的关于断开节点与分布式表的连接,同时仍保持架构在节点上运行:

函数调用 mnesia:del_table_copy(schema, mynode@host) 删除 Mnesia 系统中的节点“mynode@host”。如果调用失败 mnesia 在 'mynode@host' 上运行。其他的 mnesia 节点永远不会 尝试再次连接到该节点。注意,如果有光盘驻留 节点 'mynode@host' 上的模式,整个 mnesia 目录应该 被删除。这可以通过 mnesia:delete_schema/1 来完成。 如果失忆症是 在节点 'mynode@host' 上再次启动,并且该目录还没有 被清除,mnesia 的行为是undefined

现有的分布式架构不能保存在断开连接的节点上。您必须重新创建一个,并复制表信息。

如果您希望在您的节点上保留当前架构,您可以从中删除任何共享表,并改用纯本地表。

如果您真的希望从架构中删除节点,您可以导出数据、删除架构并创建一个新的、未分发的架构,然后导入数据以进行测试和开发。


以下是您可以在这两种情况下使用的一些有用功能:

复制记忆表

Mnesia 表可以很容易地复制,就像在这个例子中我只是为了纯粹的乐趣而编写(和测试)的:

copy_table(FromTable,ToTable) ->
    mnesia:create_table(ToTable, [
                        {attributes, mnesia:table_info(FromTable,attributes)},
                        {index, mnesia:table_info(FromTable,index)},
                        % Add other attributes to be inherited, if present
                        {record_name,FromTable},
                        {access_mode, read_write},
                        {disc_copies,[node()]}
                        ]),

    Keys = mnesia:dirty_all_keys(FromTable),
    CopyJob = fun(Record,Counter) ->
            mnesia:write(ToTable,Record,write),
            Counter + 1
            end,

    mnesia:transaction(fun() -> mnesia:foldl(CopyJob,0,FromTable) end).

此函数会将任何表(分布式或非分布式)复制到仅保留其属性和记录定义的本地计算机。你必须使用 mnesia:read


将 mnesia 表导出/导入文件

这个其他函数将一个 mnesia 表导出到一个文件,然后再次将其导入。他们需要一些小的调整才能将它们导入到任意命名的表中。 (您可以使用 mnesia:ets/1 来获得它的纯粹体验):

export_table(Table) ->
    Temp = ets:new(ignoreme,[bag,public]),
    Job  = fun(Key) ->
        [Record] = mnesia:dirty_read(Table,Key),
        ets:insert(Temp,Record) end,
    Keys = mnesia:dirty_all_keys(Table),
    [Job(Key) || Key <- Keys],
    Path = lists:concat(["./",atom_to_list(Table),".ets"]),
    ets:tab2file(Temp,Path,[{extended_info,[md5sum,object_count]}]),
    ets:delete(Temp).





import_table(Table) ->
    Path = lists:concat(["./",atom_to_list(Table),".ets"]),
    {ok,Temp} = ets:file2tab(Path,[{verify,true}]),
    {atomic,Count} = mnesia:transaction(fun() ->
        ets:foldl(fun(Record,I) -> mnesia:write(Record),I+1 end
             ,0
             ,Temp)
        end),
    ets:delete(Temp).

【讨论】:

  • 谢谢大家。但这也是我通过研究得出的结果很好的描述@berzemus
猜你喜欢
  • 2016-09-20
  • 2011-04-11
  • 1970-01-01
  • 2018-07-19
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多