Docs Menu

レプリカセットのフェイルオーバー中のロールバック

ロールバックは、 フェイルオーバー 後にノードが レプリカセット に再参加したときに、以前の プライマリ での書込み (write) 操作を元に戻します。ロールバックが必要なのは、プライマリが降格する前に、プライマリが受け入れた書込み (write) 操作をセカンダリが正常に 複製できなかった 場合だけです。 プライマリがセカンダリとしてセットに再参加すると、他のノードと間でデータベースの一貫性を維持するために、書込み (write) 操作を元に戻す、つまり "ロールバック" します。

MongoDB はロールバックを回避しようとしますが、これはまれにしか起きないはずです。ロールバックが発生する場合、ネットワーク パーティションが原因の場合が多いです。以前のプライマリの操作スループットに追いつけないセカンダリでは、ロールバックのサイズと影響が大きくなります。

プライマリが降格する前に書込み (write) 操作がレプリカセットの別のノードに複製されて、かつそのノードがレプリカセットの大部分から引き続き使用可能でアクセス可能である場合は、ロールバックは発生しません

createRollbackDataFilesパラメーターは、ロールバック中にロールバック ファイルが作成されるかどうかを制御します。

デフォルトでは、ロールバックが発生すると、MongoDB はロールバック データを BSON ファイルに書込みます。

データがロールバックされる各コレクションのロールバック ファイルは <dbpath>/rollback/<collectionUUID> ディレクトリにあり、ファイル名は次の形式になります。

removed.<timestamp>.bson

たとえば、reporting データベース内のコレクション comments のデータがロールバックされた場合、ファイルの場所は以下の通りです。

<dbpath>/rollback/20f74796-d5ea-42f5-8c95-f79b39bad190/removed.2020-02-19T04-57-11.0.bson

ここで、<dbpath>mongoddbPath です。

Tip

コレクション名

コレクション名を取得するには、MongoDB ログで rollback file を検索します。たとえば、ログファイルが /var/log/mongodb/mongod.log の場合、grep を使用して、ログ内で "rollback file" のインスタンスを検索できます。

grep "rollback file" /var/log/mongodb/mongod.log

あるいは、すべてのデータベースでループ処理を行い、一致するまで特定の UUID に対して db.getCollectionInfos() を実行してすることもできます。以下に例を挙げます。

var mydatabases=db.adminCommand("listDatabases").databases;
var foundcollection=false;
for (var i = 0; i < mydatabases.length; i++) {
let mdb = db.getSiblingDB(mydatabases[i].name);
collections = mdb.getCollectionInfos( { "info.uuid": UUID("20f74796-d5ea-42f5-8c95-f79b39bad190") } );
for (var j = 0; j < collections.length; j++) { // Array of 1 element
foundcollection=true;
print(mydatabases[i].name + '.' + collections[j].name);
break;
}
if (foundcollection) { break; }
}

ロールバックする操作がコレクション削除またはドキュメント削除の場合、コレクション削除やドキュメント削除のロールバックはロールバック データディレクトリに書込まれません。

警告

書込み操作で{ w: 1 }書込み保証が使用される場合、書込み操作が完了する前にプライマリが再起動すると、ロールバック ディレクトリはoplog hole後に送信された書込みを除外することがあります。

ロールバック ファイルの内容を読み取るには、bsondump を使用します。管理者は、ファイルの内容と、アプリケーションに関する知識に基づいて、次に取るべきアクションを決定できます。

レプリカセットの場合、書込み保証 (write concern) { w: 1 } では、プライマリでの書込み (write) 操作の確認のみを提供します。書込み (write) 操作がいずれかのセカンダリに複製される前にプライマリが降格した場合、データはロールバックされる可能性があります。これには、{ w: 1 } 書込み保証 (write concern) を使用してコミットするマルチドキュメントトランザクションで書き込まれたデータが含まれます。

クライアントに確認応答されたデータのロールバックを防ぐには、ジャーナリングを有効にして投票権を持つすべてのノードを実行し、{ w: "majority" } 書込み保証 (write concern) を使用して、書込み (write) 操作がレプリカセットのノードの過半数に伝播してから、発行元のクライアントへ確認応答を返すようにします。

MongoDB 5.0 以降では、ほとんどのMongoDB 配置で { w: "majority" } がデフォルトの書込み保証 (write concern) です。「暗黙のデフォルト書込み保証 (write concern)」を参照してください。

writeConcernMajorityJournalDefaultfalse に設定すると、MongoDB は書き込みを確認する前に、オンディスク ジャーナルに w: "majority" 書き込みが書き込まれるのを待たなくなります。そのため、"majority" 特定のレプリカセット内の大多数のノードでの一時的な損失(例: クラッシュおよび再起動)が発生したイベントにロールバックされる可能性があります。

  • 書き込み (write) の書込み保証 (write concern) に関係なく、"local" または "available"の読み取り保証 (read concern) を使用する他のクライアントは、書き込み (write) 操作が発行クライアントに確認される前に、書き込み (write) 操作の結果を確認できます。

  • "local" または "available" 読み取り保証 (read concern)を使用するクライアントは、レプリカセットのフェイルオーバー中に、後でロールバックされる可能性のあるデータを読み取ることができます。

マルチドキュメントトランザクションの操作では、トランザクションがコミットされると、トランザクション内のすべてのデータ変更が保存され、トランザクションの外部に表示されます。つまり、トランザクションが他の変更をロールバックしながら、一部の変更をコミットすることはありません。

トランザクションがコミットされるまで、トランザクションで行われたデータ変更はトランザクションの外部には表示されません。

ただし、トランザクションが複数のシャードに書き込む場合、すべての外部読み取り操作が、コミットされたトランザクションの結果がシャード全体で表示されるまで待機する必要はありません。たとえば、トランザクションがコミットされ、書込み 1 がシャード A で表示されているものの、書込み 2 がシャード B にまだ表示されていない場合、読み取り保証(read concern) "local" での外部読み取りは、書き込み 2 を見ることなく書き込み 1 の結果を読み取ることができます。

バージョン 4.2 以降、MongoDB はノードが ROLLBACK 状態になると、進行中のすべてのユーザー操作を強制終了します。

インデックス構築プロセスの詳細については、「入力済みコレクションでのインデックス構築」を参照してください。

"majority" 読み取り保証(read concern)を無効にすると、インデックスを変更する collMod コマンドがロールバックされなくなります。このような操作のロールバックが必要な場合は、影響を受けるノードをプライマリ ノードと再同期する必要があります。

MongoDB は、サイズ制限が異なる次のロールバック アルゴリズムをサポートしています。

  • タイムスタンプに回復。以前のプライマリは一貫性のある時点まで戻り、同期ソースの履歴ブランチに追いつくまで操作を適用します。これがデフォルトのロールバック アルゴリズムです。

    このアルゴリズムを使う場合、MongoDB はロールバックできるデータ量を制限しません。

  • Refetch によるロールバック。以前のプライマリは、自分のoplogと同期ソースの oplog 間の共通点を見つけます。次に、ノードが oplog 内のすべての操作を検査し、この共通点に達するまで元に戻します。Refetch によるロールバックは、設定ファイルの enableMajorityReadConcern 設定が false に設定されている場合にのみ発生します。

    このアルゴリズムを使用する場合、MongoDB がロールバックできるデータは最大 300 MB です。

    注意

    MongoDB 5.0 以降では、enableMajorityReadConcerntrue に設定されており、変更できません。

ロールバックの時間制限はデフォルトで 24 時間であり、rollbackTimeLimitSecs パラメーターを使用して設定できます。

MongoDB は、oplog 内の最初の一般的な操作から、ロールバックされるノードによる oplog の最後のエントリまでの時間として経過時間を測定します。