我需要从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群集,同时让它保持正常运行?
非常感谢任何和所有指导
答案 0 :(得分: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来完成。 如果是mnesia 再次在节点'mynode @ host'上启动,目录没有 被清除后,mnesia的行为未定义 。
现有的分布式架构无法保留在断开连接的节点上。您必须重新创建一个,并复制表信息。
如果您希望在节点上保留当前架构,可以从中删除任何共享表,而是使用纯本地表。
如果您真的希望从架构中删除该节点,您可以导出数据,删除架构并创建一个新的未分配的架构,并导入数据,以进行测试和开发。
以下是您可以在两种情况下使用的一些有用功能:
复制mnesia表
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).