いくつかの実験の後、私は次のことを発見しました:
- Mnesia は、2 つのノード間でノードが切断され、mnesia の再起動なしで再接続された場合、ネットワークが分割されていると見なしました。
- これは、切断時に Mnesia の読み取り/書き込み操作が発生しない場合でも当てはまります。
- 分断されたネットワーク イベントをクリアするには、Mnesia 自体を再起動する必要があります
force_load_table
。ネットワークが分断された後はできません。
- ネットワーク分割イベントをクリアするには、Mnesia のみを再起動する必要があります。ノード全体を再起動する必要はありません。
- Mnesia は、新たに再起動された Mnesia ノードがそのテーブル データを別の Mnesia ノードからのデータで上書きすることによって、ネットワークの分割を解決します (スタートアップ テーブル ロード アルゴリズム)。
- 通常、ノードは最も長く稼働しているノードからテーブルをコピーします (これは私が見た動作であり、これが明示的にコード化されていることを確認しておらず、他の何かの副作用ではないことを確認していません)。クラスタからノードを切断し、両方のパーティション (切断されたノードとその古いピア) に書き込みを行い、すべてのノードをシャットダウンしてから、切断されたノードを最初に開始してすべてのバックアップを再開すると、切断されたノードがマスターと見なされ、そのノードがそのノードのデータは他のすべてのノードを上書きします。テーブル比較/チェックサム/クォーラム動作はありません。
mnesia:stop(), mnesia:start()
したがって、私の質問に答えるために、データを破棄することを決定したパーティション (失われたパーティションと呼びます) 内のノードで実行することにより、セミ オンライン リカバリを実行できます。呼び出しを実行するmnesia:start()
と、ノードはパーティションの反対側のノードに接続します。負けたパーティションに複数のノードがある場合は、勝ったパーティションのノードにテーブルをロードするためのマスター ノードを設定することをお勧めします。そうしないと、負けたパーティションの別のノードからテーブルをロードする可能性があると思います。分断されたネットワーク状態に戻ります。
残念ながら、mnesia は、開始時のテーブル ロード フェーズ中のテーブル コンテンツのマージ/調整をサポートしていません。また、開始されたテーブル ロード フェーズに戻ることもできません。
マージ フェーズは特に ejabberd に適しています。これは、ノードがまだユーザー接続を持っているため、ノードが所有している/最新である必要があるユーザー レコードを認識しているからです (クラスターごとに 1 つのユーザー接続を想定)。マージ フェーズが存在する場合、ノードはユーザーデータ テーブルをフィルタリングし、接続されているユーザーのすべてのレコードを保存し、通常どおりテーブルをロードしてから、保存されたレコードを mnesia クラスターに書き戻すことができます。