MongoDB——TTL索引

441 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

TTL(Time To Live)是特殊的单字段索引,MongoDB可以使用它在一定时间或者特定时间后从集合中删除文档。对处理过期数据很友好,例如:日志数据,这些信息只需要在数据库保留有限的时间,而且这类数据占用很大。同时也支持索引查询。

创建TTL索引

要创建索引,必须在字段值为日期或者包含日期的数组字段上使用,并指定expireAfterSeconds 过期时间(以秒为单位)的选项。

db.<collection>.createIndex({<feild>: 1}, {expireAfterSeconds: <second>})

我们也可以讲非TTL的单字段索引转换为TTL索引

MongoDB 5.1开始,您可以将expireAfterSeconds选项添加到现有的单字段索引。

db.runCommand({
  "collMod": <collection>,
  "index": {
    "keyPattern": <keyPattern>,
    "expireAfterSeconds": <number>
  }
})

同样适用上述方法也可以更新expireAfterSeconds的值

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

如何实现

计算到期

到期时间,是根据索引字段的时间加上指定时间expireAfterSeconds。如果该字段是一个数组,并且索引中有多个日期值,MongoDB使用数组中的最早日期值来计算过期时间。

如果不包含日期信息,则不会过期。不包含索引字段,同样也不会过期。

如何删除

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

我们可以通过db.currentOp()看到删除操作。

删除时机

  • 索引构建完成时,会删除过期文档
  • 每60秒运行一次,不保证过期立即删除,可能存在延迟
  • 副本集由主节点来删除过期文档,从节点从主节点复制删除操作

限制

  • 单字段索引,复合索引不支持。
  • _id字段不支持
  • 和限制集合(Capped)不能同时使用
  • 不能在时间序列集合上创建
  • 不能使用createIndex()更改expireAfterSeconds现有索引的值
  • 不能在同一字段上重复创建