Docs Menu

TTL Indexes

注意

ストレージ コストを節約するためにドキュメントを削除している場合、MongoDB Atlas での Online Archive の使用がおすすめです。Atlas Online Archive は、アクセス頻度の低いデータを完全管理の S3 バケットに自動的にアーカイブするコスト効果の高いデータ階層化ツールです。

TTL インデックスは、MongoDB が特定の時間経過後または指定された時刻にコレクションからドキュメントを自動的に削除するために使用できる特別な単一フィールドのインデックスです。データの有効期限設定は、機械生成のイベントデータ、ログ、セッション情報など、データベースに一定の期間だけ保持する必要がある情報に対して便利です。

MongoDB Atlas でホストされている配置向けに UI で 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 }
)

重要

Starting in MongoDB 6.3, you can create partial TTL indexes on time series collections. When you create a time series collection, you can include the optional expireAfterSeconds field, which deletes documents after the specified time.

For example, create the following weather data time series collection and set the expireAfterSeconds field to delete documents after 24 hours:

db.createCollection(
"weather24h",
{
timeseries: {
timeField: "timestamp",
metaField: "sensor",
granularity: "hours"
},
expireAfterSeconds: 86400
}
)

You can also create a TTL index on the collection with a partialFilterExpression field. These indexes use the collection's timeField as the key field. You also specify:

  • An expireAfterSeconds field, which sets an explicit expiration time for the subset of documents. Even if you had set the expireAfterSeconds field when creating the collection, the partialFilterExpression field lets you set a different, shorter expiration period for the subset of matching documents.

  • A partial filter expression on the metaField. The partial filter expression defines the set of documents that will expire in the time defined by the expireAfterSeconds field.

The following TTL index matches documents in the "weather24h" collection where the "sensor" field is set to "MDB_NYC", and deletes them after 1 hour, overriding the default 24 hours we set when creating the collection:

db.weather24h.createIndex(
{ "timestamp": 1 },
{
expireAfterSeconds: 3600,
partialFilterExpression: { "sensor": { $eq: "MDB_NYC" } }
}
)

重要

コレクションの expireAfterSeconds 値が部分的な TTL インデックスの expireAfterSeconds より小さい場合、コレクションは短い方の時間経過後にドキュメントを削除するため、TTL インデックスは効果がありません。

1970-01-01T00:00:00.000Z の前または 2038-01-19T03:14:07.000Z の後に timeField タイムスタンプがあるドキュメントが時系列コレクションに含まれる場合、TTL(time to live) 機能によってコレクションからドキュメントが削除されることはありません。

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
}
})

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 は配列内の最も低い日付値(最も近い日付値)を使用して有効期限のしきい値を計算します。

時系列コレクションの場合、TTL インデックスは、その中のすべてのドキュメントの有効期限が切れると、バケット データの削除も行います。これは、バケットのタイムスタンプの上限に expireAfterSeconds 値を加えた値に等しくなります。たとえば、バケットに 2023-03-27T18:29:59Z までのデータが含まれ、expireAfterSeconds が 300 の場合、TTL インデックスは 2023-03-27T18:34:59Z の後にバケットを期限切れにします。

ドキュメント内のインデックス付きフィールドに 1 つ以上の日付値が含まれていない場合、ドキュメントは有効期限切れになりません。

インデックス フィールドが含まれていないドキュメントは、有効期限切れになりません。

mongod のバックグラウンド スレッドは、インデックスの値を読み取り、コレクションから期限切れのドキュメントを削除します。

TTL スレッドによって実行される進行中の削除操作は、 db.currentOp()の出力に表示されます。 TTL スレッドがドキュメントを削除すると、 metrics.ttl.deletedDocumentsサーバー ステータス メトリクスが増加します。

MongoDB 6.1 以降、次の機能を使用できます。

  • MongoDB は効率を向上するために、複数のドキュメントの削除をバッチ処理する場合があります。

  • explain コマンドの結果には、バッチ処理されたドキュメント削除のための新しい BATCHED_DELETE ステージが含まれています。

1970-01-01T00:00:00.000Z の前または 2038-01-19T03:14:07.000Z の後に timeField タイムスタンプがあるドキュメントが時系列コレクションに含まれる場合、TTL(time to live) 機能によってコレクションからドキュメントが削除されることはありません。

TTL バックグラウンド削除プロセスは、各 TTL インデックスで期限切れのドキュメントをチェックします。 TTL インデックスごとに、次のいずれかの条件が満たされるまで、バックグラウンド プロセスはドキュメントを削除します。

  • プロセスは、現在のインデックスから50000ドキュメントを削除します。

  • プロセスでは、現在のインデックスからドキュメントを削除するのに 1 秒かかります。

  • 期限切れのドキュメントはすべて、現在のインデックスから削除されます。

その後、プロセスは次のインデックスに移動します。 プロセスが各 TTL インデックスを 1 回通過すると、現在のサブパスは完了し、新しいサブパスが残りの期限切れドキュメントのチェックを開始します。 TTL モニターがすべての TTL インデックスから可能なすべての候補ドキュメントを削除すると、パスは完了します。

さらに、 プロセスは現在の削除ループを60秒ごとに停止して、1 回の大きな削除に時間がかかりすぎるのを防ぎます。 このような状況が発生すると、現在のサブパスは終了し、新しいサブパスが開始されます。

パスとサブパスはそれぞれmetrics.ttl.passesmetrics.ttl.subPassesサーバー ステータス メトリクスで追跡されます。

MongoDB は、プライマリでインデックスの構築が完了するとすぐに、期限切れのドキュメントまたは時系列バケットの削除を開始します。インデックス構築プロセスの詳細については、「入力されたコレクションでのインデックス構築」を参照してください。

TTL インデックスは、有効期限が切れたデータがその期限直後に削除されることを保証するものではありません。ドキュメントの有効期限が切れてから MongoDB がデータベースからドキュメントを削除するまでの間にタイムラグが生じる可能性があります。

期限切れのドキュメントを削除するバックグラウンド タスクは、60 秒ごとに実行されるため、ドキュメントの有効期限が切れてからバックグラウンド タスクが実行されるまでの間に、ドキュメントがコレクションに残ることがあります。MongoDB は、インデックスの完了から 0~60 秒後にドキュメントの削除を開始します。

削除操作の間隔は mongod インスタンスのワークロードによって異なるため、バックグラウンド タスクの実行間隔が 60 秒を超えると、有効期限切れのデータがしばらく残る可能性があります。

TTL タスクが開始する削除操作は他の削除操作と同様に、フォアグラウンドで実行されます。

TTL バックグラウンド スレッドはレプリカセット ノードで、ノードがプライマリ状態にある場合にのみドキュメントを削除します。TTL バックラウンド スレッドは、ノードがセカンダリ状態にある場合はアイドルになります。セカンダリ ノードはプライマリでの削除操作をレプリケートします。

TTL インデックスは、TTL 以外のインデックスと同様にクエリをサポートします。

mongod がスタンドアロンモードで実行され、system.local.replset コレクションにデータが含まれている場合、TTL モニターは停止します。レプリカセットのノードをレプリカセットから取り出してスタンドアロンとして実行する場合、TTL モニターは無効になります。