在mnesia集群中,查询哪个节点?

时间:2009-04-06 18:43:27

标签: erlang mnesia

假设您在节点A和B上复制了一个mnesia表。如果在节点C上没有包含该表的副本,我执行mnesia:change_config(extra_db_nodes, [NodeA, NodeB]),然后在节点CI上执行{{1} }节点C如何选择在哪个节点的表副本上执行查询?

2 个答案:

答案 0 :(得分:14)

根据我自己的研究答案,问题是 - 它将选择最近连接的节点。如果找到错误,我将非常感激 - mnesia是一个非常复杂的系统!

作为邮件列表上的Dan Gudmundsson pointed out选择要查询的远程节点的算法在mnesia_lib:set_remote_where_to_read/2中定义。它是以下

set_remote_where_to_read(Tab, Ignore) ->
    Active = val({Tab, active_replicas}),
    Valid =
       case mnesia_recover:get_master_nodes(Tab) of
           [] ->  Active;
           Masters -> mnesia_lib:intersect(Masters, Active)
       end,
    Available = mnesia_lib:intersect(val({current, db_nodes}), Valid -- Ignore),
    DiscOnlyC = val({Tab, disc_only_copies}),
    Prefered  = Available -- DiscOnlyC,
    if
       Prefered /= [] ->
           set({Tab, where_to_read}, hd(Prefered));
       Available /= [] ->
           set({Tab, where_to_read}, hd(Available));
       true ->
           set({Tab, where_to_read}, nowhere)
    end.

因此它获取active_replicas列表(即候选列表),可选择将列表缩小为表的主节点,删除要忽略的表(出于任何原因),将列表缩小到当前连接的节点,然后选择以下顺序:

  1. 首先非 - disc_only_copies
  2. 任何可用节点
  3. 最重要的部分实际上是active_replicas的列表,因为它确定了候选列表中节点的顺序。

    active_replicas的列表是由mnesia_controller:add_active_replica/*从新连接的节点到旧节点(即之前在集群中的节点)的远程调用形成的,其归结为函数add/1它将项目添加为列表的头部。

    因此问题的答案 - 它会选择最近连接的节点

    注意: 要查看给定节点上的活动副本列表,您可以使用此(脏黑客)代码:

    [ {T,X} || {{T,active_replicas}, X} <- ets:tab2list(mnesia_gvar) ]. 
    

答案 1 :(得分:-1)

嗯,节点C需要联系节点A或节点B才能进行查询。因此,节点C必须自己决定执行查询的表副本。

如果你需要更多的东西,你需要有一些算法来决定查询哪个节点,甚至复制节点C上的表(这通常取决于你想要/需要什么样的特征)

如果节点A和节点B形成或是数据库集群的一部分,那么一个良好的开端可能是循环算法(或随机,如你所建议的那样)。

相关问题