Docs 菜单

Docs 主页开发应用程序MongoDB Manual

TTL 索引

在此页面上

  • 创建 TTL 索引
  • 将非 TTL 单字段索引转换为 TTL 索引
  • 更改TTL 索引的 expireAfterSeconds
  • 行为
  • 限制

注意

如果要删除文档以节省存储成本,请考虑 MongoDB Atlas 中的 Online Archive 。 Online Archive 会自动将不常访问的数据存档到完全托管的 S3 存储桶,以实现经济高效的数据分层。

TTL 索引是特殊的单字段索引,MongoDB 可以在一定时间后或在特定时钟时间使用这种索引自动从集合中删除文档。数据过期对于某些类型的信息(例如机器生成的事件数据、日志和会话信息)很有用,这些信息仅需要在数据库中保留有限的时间。

警告

创建 TTL 索引后,可能需要一次性删除大量符合条件的文档。如此大的工作负载可能会导致服务器出现性能问题。为了避免此类问题,请计划在非工作时间创建索引,或者在为将来的文档创建索引之前,批量删除符合条件的文档。

要创建 TTL 索引,请使用 createIndex()。指定一个日期类型或包含日期类型值的数组的索引字段。使用 expireAfterSeconds 选项指定 TTL 值(以秒为单位)。

TTL 索引 expireAfterSeconds 值必须介于 02147483647(包含两者)之间。

例如,要在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“生存时间”功能不会从集合中删除任何文档。

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

以下示例更改 tickets 集合上具有模式 { "lastModifiedDate": 1 } 的索引的 expireAfterSeconds 值:

db.runCommand({
"collMod": "tickets",
"index": {
"keyPattern": { "lastModifiedDate": 1 },
"expireAfterSeconds": 100
}
})

TTL 索引在索引字段值经过指定秒数后使文档过期;即过期阈值是索引字段值加上指定秒数。

如果字段为数组,且索引中有多个日期值,MongoDB 会使用数组中最低(即最早)日期值计算过期阈值。

如果文档中的索引字段不是日期或保存一个或多个日期值的数组,则文档不会过期。

如果文档不包含索引字段,则文档将不会过期。

mongod 中的后台线程会读取索引中的值,并从集合中删除过期文档

当 TTL 线程处于活跃状态时,您将在 db.currentOp() 的输出或数据库分析器收集的数据中看到删除操作。

如果时间序列集合包含时间戳在 1970-01-01T00:00:00.000Z 之前或 2038-01-19T03:14:07.000Z 之后为 timeField 的文档,则 TTL“生存时间”功能不会从集合中删除任何文档。

索引在节点上构建完成后,MongoDB 会立即删除过期文档。 有关索引构建过程的更多信息,请参阅在已填充collection上构建索引。

TTL 索引并不保证过期数据会在过期后立即删除。 文档过期时间和 MongoDB 从数据库中删除文档的时间之间可能存在延迟。

删除过期文档的后台任务每 60 秒运行一次。因此,在文档过期和后台任务运行之间的时间段内,文档可能会保留在集合中。MongoDB 在索引完成后 0 到 60 秒开始删除文档。

由于删除操作的持续时间取决于 mongod 实例的工作负载,因此过期数据可能会在后台任务运行之间的 60 秒间隔时间以后存在一段时间。

由 TTL 任务启动的删除操作在前台运行,就像其他删除操作一样。

副本集成员上,TTL 后台线程在成员处于状态时删除文档。当成员处于状态时,TTL 后台线程处于空闲状态。成员复制主成员的删除操作。

TTL 索引支持查询的方式与非 TTL 索引相同。

← 索引属性