TTL Indexes

在本页面

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

若要创建 TTL 索引,请在其值为date或包含date values的数组的字段上使用db.collection.createIndex()方法和expireAfterSeconds选项。

例如,要在eventlog集合的lastModifiedDate字段上创建 TTL 索引,请在mongo shell 中使用以下操作:

db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )

Behavior

数据过期

从索引字段值开始经过指定的秒数后,TTL 索引使文档过期;即,到期阈值是索引字段值加上指定的秒数。

如果该字段是数组,并且索引中有多个日期值,则 MongoDB 使用数组中的最低(即最早的)日期值来计算到期阈值。

如果文档中的索引字段不是date或包含日期值的数组,则该文档不会过期。

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

Delete Operations

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

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

删除操作的时间

一旦索引在primary上完成构建,MongoDB 就开始删除过期的文档。有关索引构建过程的更多信息,请参见填充集合上的索引构建操作

TTL 索引不能保证过期的数据将在过期后立即删除。从文档过期到 MongoDB 从数据库删除文档之间可能会有延迟。

删除过期文档的后台任务每 60 秒运行一次。结果,在文档期满和后台任务运行之间的时间段内,文档可能会保留在集合中。

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

Replica Sets

replica set个成员上,当成员处于状态primary时,TTL 仅后台线程删除文档。当成员处于状态secondary时,TTL 背景线程处于空闲状态。 Secondary成员从主服务器复制删除操作。

查询支持

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

MMAPv1 上的记录分配

使用 MMAPv1 存储引擎,具有 TTL 索引的集合已自动启用usePowerOf2Sizes。您不能为集合修改此设置。启用usePowerOf2Sizes后,相对于数据大小,MongoDB 必须分配更多的磁盘空间。这种方法有助于减轻由频繁的删除操作引起的存储碎片的可能性,并导致更可预测的存储使用模式。

Restrictions

  • TTL 索引是单字段索引。 Compound indexes不支持 TTL,请忽略expireAfterSeconds选项。

  • _id字段不支持 TTL 索引。

  • 您无法在capped collection上创建 TTL 索引,因为 MongoDB 无法从有上限的集合中删除文档。

  • 您不能使用createIndex()更改现有索引的expireAfterSeconds的值。而是将collMod数据库命令与index收集标志一起使用。否则,要更改现有索引的选项的值,必须首先删除索引并重新创建。

  • 如果某个字段已经存在非 TTL 单字段索引,则无法在同一字段上创建 TTL 索引,因为您无法创建具有相同密钥规格且仅选项不同的索引。要将非 TTL 单字段索引更改为 TTL 索引,必须首先删除该索引,然后使用expireAfterSeconds选项重新创建。

  • 通过设置 TTL 使集合中的数据过期