TTL Indexes
注意
ストレージ コストを節約するためにドキュメントを削除している場合、MongoDB Atlas の Online Archive の使用がおすすめです。Atlas Online Archive は、アクセス頻度の低いデータを完全自己管理型の S3 バケットに自動的にアーカイブするコスト効果の高いデータ階層化ツールです。
TTL インデックスは、MongoDB が特定の時間経過後または指定された時刻にコレクションからドキュメントを自動的に削除するために使用できる特別な単一フィールドのインデックスです。データの有効期限設定は、機械生成のイベントデータ、ログ、セッション情報など、データベースに一定の期間だけ保持する必要がある情報に対して便利です。
MongoDB Atlas でホストされている配置向け に UI で TTL インデックスを作成および管理 できます
TTL インデックスの作成
警告
TTL インデックスを作成すると、一度に削除する対象ドキュメントの数が非常に多くなる場合があります。こうした大きなワークロードは、サーバーでパフォーマンスの問題が生じる原因になることがあります。こうした問題を回避するには、営業時間外にインデックスを作成するか、対象となるドキュメントをバッチ単位で削除してからその後に作成されるドキュメントのインデックスを作成します。
TTL インデックスを作成するには、createIndex()
を使用します。Date 型または Date 型の値を含む配列のインデックス フィールドを指定します。expireAfterSeconds
オプションを使って TTL 値を秒単位で指定します。
TTLインデックスの expireAfterSeconds
値は、0
から 2147483647
の範囲内(両端を含む)である必要があります。
たとえば、 eventlog
コレクションのlastModifiedDate
フィールドに TTL 値3600
秒を使用して TTL インデックスを作成するには、 mongosh
で次の操作を使用します。
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
1970-01-01T00:00:00.000Z
の前または 2038-01-19T03:14:07.000Z
の後に timeField
タイムスタンプがあるドキュメントが時系列コレクションに含まれる場合、TTL(time to live) 機能によってコレクションからドキュメントが削除されることはありません。
TTL 以外の単一フィールド インデックスの TTL インデックスへの変換
MongoDB 5.1 以降では、既存の単一フィールド インデックスに expireAfterSeconds
オプションを追加できます。TTL 以外の単一フィールド インデックスを TTL インデックスに変更するには、collMod
データベースコマンドを使用します。
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
次の例では、パターン { "lastModifiedDate": 1 }
を含む TTL 以外の単一フィールド インデックスを TTL インデックスに変換しています。
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
expireAfterSeconds
TTL インデックスの 値の変更
TTL インデックスの expireAfterSeconds
値を変更するには、collMod
データベースコマンドを使用します。
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
次の例では、パターン { "lastModifiedDate": 1 }
を含むインデックスの expireAfterSeconds
の値を tickets
コレクションで変更しています。
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
重要
TTL インデックスのexpireAfterSeconds
パラメータを更新する前に、次の点を考慮してください。
パラメータを変更しても、インデックスの完全な再構築は さ
expireAfterSeconds
れません 。triggerただし、expireAfterSeconds
の値を減らすと、多くのドキュメントが即座に削除の対象となる可能性があり、削除操作が増加してパフォーマンスの問題が発生する可能性があります。TTL インデックスを更新する前に、ドキュメントを小さなバッチで手動で削除することをお勧めします。 これにより、クラスターへの影響を制御することができます。
多くのドキュメントを削除すると、ストレージ ファイルが断片化され、パフォーマンスにさらに影響が生じます。 スペースを再利用し、ストレージを最適化するには、コレクションに対して圧縮コマンドを実行するか、最初の同期を実行する必要がある場合があります。
動作
データの有効期限
TTL インデックスは、インデックス フィールド値から指定された秒数が経過するとドキュメントが期限切れになります。 有効期限のしきい値は、インデックス フィールドの値に、指定された秒数を加えた値になります。
フィールドが配列で、インデックスに複数の日付値がある場合、MongoDB は配列内の最も低い日付値(最も近い日付値)を使用して有効期限のしきい値を計算します。
ドキュメント内のインデックス フィールドが date でも、1 つ以上の date 値を保持する配列でもない場合、ドキュメントは期限切れになりません。
インデックス フィールドが含まれていないドキュメントは、有効期限切れになりません。
削除操作
mongod
のバックグラウンド スレッドは、インデックスの値を読み取り、コレクションから期限切れのドキュメントを削除します。
TTL スレッドによって実行される進行中の削除操作は、 db.currentOp()
の出力に表示されます。 TTL スレッドがドキュメントを削除すると、 metrics.ttl.deletedDocuments
サーバー ステータス メトリクスが増加します。
1970-01-01T00:00:00.000Z
の前または 2038-01-19T03:14:07.000Z
の後に timeField
タイムスタンプがあるドキュメントが時系列コレクションに含まれる場合、TTL(time to live) 機能によってコレクションからドキュメントが削除されることはありません。
削除操作のタイミング
MongoDB は、プライマリでインデックスの構築が完了するとすぐに、期限切れのドキュメントの削除を開始します。 インデックス構築プロセスの詳細については、「入力済みコレクションでのインデックス構築 」を参照してください。
TTL インデックスは、有効期限が切れたデータがその期限直後に削除されることを保証するものではありません。 ドキュメントの有効期限が切れてから MongoDB がデータベースからドキュメントを削除するまでの間にタイムラグが生じる可能性があります。
期限切れのドキュメントを削除するバックグラウンド タスクは、60 秒ごとに実行されるため、ドキュメントの有効期限が切れてからバックグラウンド タスクが実行されるまでの間に、ドキュメントがコレクションに残ることがあります。MongoDB は、インデックスの完了から 0~60 秒後にドキュメントの削除を開始します。
削除操作の間隔は mongod
インスタンスのワークロードによって異なるため、バックグラウンド タスクの実行間隔が 60 秒を超えると、有効期限切れのデータがしばらく残る可能性があります。
TTL タスクが開始する削除操作は他の削除操作と同様に、フォアグラウンドで実行されます。
レプリカセット
TTL バックグラウンド スレッドはレプリカセット ノードで、ノードがプライマリ状態にある場合にのみドキュメントを削除します。TTL バックラウンド スレッドは、ノードがセカンダリ状態にある場合はアイドルになります。セカンダリ ノードはプライマリでの削除操作をレプリケートします。
クエリのサポート
TTL インデックスは、TTL 以外のインデックスと同様にクエリをサポートします。
制限事項
TTL インデックスは単一フィールドのインデックスです。複合インデックスは TTL をサポートしておらず、
expireAfterSeconds
オプションを無視します。_id
フィールドは TTL インデックスをサポートしていません。上限付きコレクションでは TTL インデックスを作成できません。
時系列コレクションでは TTL インデックスを作成できません。 代わりに、時系列コレクションの自動削除によって同様の機能が提供されます。
既存インデックスの
expireAfterSeconds
値を変更するために、createIndex()
は使用できません。代わりに、collMod
データベースコマンドを使用してください。詳細については、「TTL インデックスのexpireAfterSeconds
値の変更」を参照してください。TTL 以外の単一フィールド インデックスがフィールドにすでにある場合、同じフィールドに TTL インデックスを作成できません。キー仕様が同じで、オプションのみが異なるインデックスは作成できないためです。TTL 以外の単一フィールド インデックスを TTL インデックスに変更するには、
collMod
データベースコマンドを使用します。