ノード A と B でレプリケートされた mnesia テーブルがあるとします。テーブルのコピーを含まないノード C では、私は を実行しmnesia:change_config(extra_db_nodes, [NodeA, NodeB])
、次にノード CI でmnesia:dirty_read(user, bob)
ノード C はどのノードのテーブルのコピーを選択するかを実行します。でクエリを実行しますか?
2 に答える
質問に対する私自身の調査によると、最後に接続されたノードが選択されます。エラーが見つかった場合は指摘していただけるとありがたいです - 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 のリスト (つまり、候補のリスト) を取得し、オプションでリストをテーブルのマスター ノードに縮小し、(何らかの理由で) 無視するテーブルを削除し、リストを現在接続されているノードに縮小し、次の順序で選択します。 :
- 最初の非
disc_only_copies
- 利用可能な任意のノード
実際、最も重要な部分は のリストですactive_replicas
。これは、候補リスト内のノードの順序を決定するためです。
のリストは、新しく接続されたノードから古いノード (つまり、以前にクラスタにあったノード) へactive_replicas
の のリモート呼び出しによって形成されます。これは、アイテムをリストの先頭として追加する関数に要約されます。mnesia_controller:add_active_replica/*
add/1
したがって、質問に対する答えは、最後に接続されたノードを選択するということです。
注: 特定のノードでアクティブなレプリカのリストを確認するには、次の (ダーティ ハック) コードを使用できます。
[ {T,X} || {{T,active_replicas}, X} <- ets:tab2list(mnesia_gvar) ].