13

假设您在节点 A 和 B 上复制了一个 mnesia 表。如果在节点 C 上不包含表的副本,我会这样做mnesia:change_config(extra_db_nodes, [NodeA, NodeB]),然后在节点 CI 上执行mnesia:dirty_read(user, bob)节点 C 如何选择要复制到哪个节点的表副本执行查询?

4

2 回答 2

14

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

正如Dan Gudmundsson 指出的,选择要查询的远程节点的邮件列表算法在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. 任何可用节点

最重要的部分实际上是 的列表active_replicas,因为它决定了候选列表中节点的顺序。

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

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

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

[ {T,X} || {{T,active_replicas}, X} <- ets:tab2list(mnesia_gvar) ]. 
于 2009-04-07T15:23:55.017 回答
-1

那么,节点 C 需要联系节点 A 或节点 B 才能进行查询。因此节点 C 必须自己决定在哪个表副本上执行查询。

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

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

于 2009-04-07T13:26:46.657 回答