sql >> データベース >  >> NoSQL >> MongoDB

二次の無限の回復状態

    問題(最も可能性が高い)

    プライマリの最後の操作は「2015-05-15T02:10:56Z」からですが、セカンダリになる最後の操作は「2015-05-14T11:23:51Z」からです。これはおおよその違いです。 15時間。そのウィンドウは、レプリケーションoplogウィンドウ(oplogの最初と最後の操作エントリの時間の差)をはるかに超える可能性があります。簡単に言うと、プライマリでの操作が多すぎて、セカンダリで追いつくことができません。

    もう少し複雑です(簡略化されていますが)。最初の同期中、2次同期元のデータは、特定の時点のデータです。その時点のデータが同期されると、セカンダリはoplogに接続し、その時点と現在の間に行われた変更をoplogエントリに従って適用します。これは、oplogが上記の時点までのすべての操作を保持している限りうまく機能します。ただし、oplogのサイズには制限があります(これは、いわゆる上限付きコレクションです。 )。したがって、最初の同期中にoplogが保持できるよりも多くの操作がプライマリで発生している場合、最も古い操作が「フェードアウト」します。セカンダリは、プライマリと同じデータを「構築」するために必要なすべての操作が利用できるわけではないことを認識し、同期の完了を拒否し、RECOVERYに留まります。 モード。

    ソリューション

    この問題は既知の問題であり、バグではありませんが、MongoDBの内部動作と、開発チームによるいくつかのフェイルセーフの仮定の結果です。したがって、状況に対処するいくつかの方法があります。残念ながら、データを保持するノードは2つしかないため、すべてダウンタイムが発生します。

    オプション1:oplogサイズを増やす

    これは私の好みの方法です。問題を一度だけ、そして(一種の)すべての問題に対処するからです。ただし、他のソリューションよりも少し複雑です。高レベルの観点から、これらはあなたが取るステップです。

    1. プライマリをシャットダウンします
    2. データファイルへの直接アクセスを使用して、oplogのバックアップを作成します
    3. mongodを再起動します スタンドアロンモードで
    4. 現在のoplogを一時的なコレクションにコピーします
    5. 現在のoplogを削除する
    6. 希望のサイズでoplogを再作成します
    7. 一時的なコレクションから光沢のある新しいoplogにoplogエントリをコピーして戻します
    8. mongodを再起動します レプリカセットの一部として

    セカンダリのoplogを増やすことを忘れないでください。これは、将来のある時点でプライマリになる可能性があるためです。

    詳細については、「oplogのサイズを変更する」をお読みください。 レプリカセットのメンテナンスに関するチュートリアル

    オプション2:同期中にアプリをシャットダウンする

    オプション1が実行可能でない場合、他の唯一の解決策は、アプリケーションをシャットダウンしてレプリカセットに負荷をかけ、同期を再開して、完了しすぎるのを待つことです。転送するデータの量に応じて、数時間で計算します。

    個人的なメモ

    oplogウィンドウの問題はよく知られています。レプリカセットとシャードクラスターはMongoDBを使用して簡単にセットアップできますが、それらを適切に維持するには、かなりの知識と経験が必要です。基本を知らずに、複雑なセットアップでデータベースほど重要なものを実行しないでください。何か悪い(tm)が発生した場合、FUBARの状況につながる可能性があります。



    1. Nodejs Mongoose-コールバック地獄を回避する方法は?

    2. Node.jsを使用したMongoDB操作でのコールバック

    3. InvalidDocument:オブジェクトをエンコードできません:<ユーザー:ユーザーオブジェクト>MongoEngineを使用したReferenceField

    4. 配列内の複数の基準に一致する