oplog(操作ログ)は、データベースに保存されているデータを変更するすべての操作のローリング レコードを保持する特別な 上限付きコレクションです。書き込み操作によってデータが変更されない場合、または書き込み操作が失敗した場合、oplog エントリは作成されません。
他の上限付きコレクションとは異なり、oplog はmajority commit point の削除を避けるため、設定されたサイズ制限を超えて拡大する場合があります。
MongoDB はプライマリにデータベース操作を適用し、その操作をプライマリの oplog に記録します。次に、セカンダリノードがこれらの操作をコピーして非同期プロセスで適用します。すべてのレプリカセット ノードには local.oplog.rsコレクション内の oplog のコピーが含まれており、これによりデータベースの最新の状態を維持できます。
レプリケーションを容易にするために、レプリカセットの全ノードは他の全ノードにハートビート(ping)を送信します。任意のセカンダリノードが、他の任意のノードから oplog エントリをインポートできます。
毎回の oplog 操作は冪等です。つまり、oplog 操作は、対象データセットに 1 回適用しても複数回適用しても同じ結果を生成します。
Oplog サイズ
レプリカセット ノードを初めて起動するときに oplog サイズを指定しない場合、MongoDB はデフォルト サイズの oplog を作成します。
- Unix および Windows システムの場合
デフォルトの oplog サイズは ストレージ エンジン によって異なります。
ストレージ エンジンデフォルトの oplog サイズディスクの空き容量の 5%
物理メモリの 5%
デフォルトの oplog のサイズには、次の制約があります。
oplog の最小サイズは 990 MB です。空きディスク領域または物理メモリ(ストレージ エンジンに基づいて適用可能な方)の 5% が 990 MB 未満の場合、デフォルトの oplog サイズは 990 MB です。
デフォルトの oplog の最大サイズは 50 GB です。空きディスク領域または物理メモリ(ストレージ エンジンに基づいて適用可能な方)の 5% が 50 GB より大きい場合、デフォルトの oplog サイズは 50 GB です。
- 64 ビット macOS システムの場合
デフォルトの oplog サイズは、ストレージ エンジンに応じて、空きディスク領域または物理メモリの 192 MB です。
ストレージ エンジンデフォルトの oplog サイズ192 MB の空きディスク容量
192 MB の物理メモリ
ほとんどの場合は、デフォルトのoplogサイズで十分です。例、 oplog が空きディスク容量の 5% で、24 時間の操作でいっぱいになった場合、セカンダリは最大 24 時間、 oplogからのエントリのコピーを停止することができ、レプリケーションの継続に支障が出るほど情報が古くなることはありません。
mongodが oplog を作成する前に、 oplogSizeMBオプションでサイズを指定できます。レプリカ セット ノードを初めて起動したら、 replSetResizeOplog管理コマンドを使用して oplog サイズを変更します。replSetResizeOplogにより、mongod プロセスを再起動せずに oplog のサイズを動的に変更できます。
最小 oplog 保持期間
oplog エントリを保持する最小時間数を指定できます。ここで、 mongodは次の条件の 両方 が満たされている場合にのみ oplog エントリを削除します。
oplog がの最大設定サイズ に達しました。
oplog エントリーは、ホスト システム クロックに基づいて構成された時間数よりも以前のものです。
デフォルトでは、MongoDB は oplog の最小保持期間を設定せず、設定された最大 oplog サイズを維持するために、最も古いエントリから oplog を自動的に切り捨てます。
mongodの起動時に最小 oplog 保持期間を構成するには、次のいずれかを実行します。
storage.oplogMinRetentionHours設定をmongod構成ファイルに追加します。または
--oplogMinRetentionHoursコマンドライン オプションを追加します。
実行中のmongodで最小 oplog 保持期間を設定するには、 replSetResizeOplogを使用します。mongodの実行中に最小 oplog 保持期間を設定すると、スタートアップ時に設定された値が上書きされます。対応する構成ファイルの設定またはコマンドラインのオプションの値を更新して、これらの変更がサーバーの再起動後も保持されるようにする必要があります。
oplog window
oplogエントリにはタイムスタンプが付けられます。oplog windowは、 oplog内の最新のタイムスタンプと最も古いタイムスタンプの間の時間差です。セカンダリノードがプライマリノードとの接続を失った場合、oplog window内で接続が復元された場合にのみ、レプリケーションを使用して再度同期できます。
より大きな Oplog サイズを必要とする可能性のあるワークロード
レプリカセットのワークロードが次のいずれかのパターンに似ていると予測できる場合は、デフォルトよりも大きい oplog を作成することをお勧めします。逆に、アプリケーションが主に読み取りを実行し、書き込み操作は最小限に抑える場合は、より小さな oplog で十分な場合があります。
複数のドキュメントの一括更新
oplog は、冪等性を維持するために、複数のアップデートを個別の操作に変換する必要があります。これにより、データサイズやディスク使用量がそれに応じて増加することなく、大量の oplog スペースが使用される可能性があります。
削除データ量が挿入データ量と等しい
挿入したデータとほぼ同量のデータを削除した場合、データベースのディスク使用量がログのサイズはかなり大きくなる可能性があります。
大量のインプレース更新
ワークロードの大部分がドキュメントのサイズを増加させない更新である場合、データベースは多数の操作を記録しますが、ディスク上のデータの量は変更されません。
Oplog Status
操作のサイズや時間範囲などの oplog ステータスを表示するには、 rs.printReplicationInfo()メソッドを発行します。Oplog ステータスの詳細については、「Oplog のサイズを確認する」を参照してください。
レプリケーションラグとフロー制御
さまざまな例外的な状況で、セカンダリの oplog の更新が、必要なパフォーマンス時間よりも遅れる可能性があります。セカンダリ ノードからの db.getReplicationInfo() とレプリケーションステータス出力を使用して、レプリケーションの現在の状態を評価し、意図しないレプリケーション遅延が発生していないかどうかを判断します。
管理者は、 majority
committedの遅延を設定可能な最大値flowControlTargetLagSeconds以下に抑えることを目的として、プライマリが書込み (write) を適用する速度を制限できます。
デフォルトのフロー制御は、enabled です。
詳細については、「レプリケーションラグ」を参照してください。
低速な Oplog アプリケーション
レプリカセットのセカンダリ ノードは、低速操作のしきい値よりも長い時間がかかる oplog のエントリを記録します。該当するメッセージは、applied op: <oplog entry> took
<num>msというテキストを含むREPLコンポーネの下のセカンダリでloggedされます。
2018-11-16T12:31:35.886-05:00 I REPL [repl writer worker 13] applied op: command { ... }, took 112ms
セカンダリでの低速 oplog を適用したロギングは以下のようになります。
logLevel/systemLog.verbosityレベル(またはsystemLog.component.replication.verbosityレベル)の影響を受けない。つまり、 oplogエントリの場合、セカンダリは低速oplogエントリのみをログに記録します。冗長レベルを上げても、すべてのoplogエントリがログわけではありません。プロファイラーによって取得されず、プロファイリング レベルの影響を受けません。
低速操作のしきい値の設定については、以下を参照してください。
profileコマンドまたはdb.setProfilingLevel()シェルヘルパー メソッド。
oplog コレクションの動作
MongoDB 配置で WiredTiger ストレージ エンジンを使用している場合は、local.oplog.rsをレプリカセットのノードからdropすることはできません。スタンドアロンの MongoDB インスタンスからlocal.oplog.rsコレクションを削除することはできません。mongodでは、ノードがダウンした場合のノードのレプリケーションの復元の両方に oplog が必要です。
MongoDB5.0 以降では、 レプリカセット として実行中のクラスター上の oplog への手動書き込み操作は実行できなくなりました。スタンドアロン インスタンスとして実行中に oplog への書き込み操作を実行する場合は、MongoDB サポートのガイダンスに必ず従う必要があります。