持续创作,加速成长!这是我参与「掘金日新计划 · 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现有索引的值 - 不能在同一字段上重复创建