定义
TTL(Time To Live)索引是一种特殊类型的单字段索引,通过配置过期属性实现对文档的自动过期删除。
运行逻辑
MongoDB会开启一个后台线程读取该TTL索引的值来判断文档是否过期。
- 后台线程每60秒触发一次删除任务
如果删除的数据量较大,会存在上一次的删除未完成,而下一次的任务已经开启的情况 - 对于副本集而言,TTL索引的后台进程只会在primary节点开启
从节点的数据删除是由主库删除后产生的oplog同步来完成 - TTL索引除了有expireAfterSeconds属性外,和普通索引一样
限制
- 只支持对单个字段创建TTL索引
- _id列不支持TTL索引
- 固定集合(capped collection)不支持TTL索引
- 不支持用createIndex() 修改expireAfterSeconds属性
- 一个列只能创建普通索引或TTL索引
- 如果一个列已经存在索引,则需要先将该索引drop后才能重建为TTL索引
演示
db.collection.createIndex(keys, options)
添加测试数据:
> for (i = 0; i < 10; i++) {
db.machineLog.insert({
"content": "机械日志" + i,
"createdAt": new Date()
})
}
添加TTL索引,5分钟后数据失效并删除
> db.machineLog.createIndex({createdAt:1}, {expireAfterSeconds:300})
查看数据:
> db.machineLog.find()
{
"_id": ObjectId("5ff18eff9d594f01396c9ea7"),
"content": "机械日志0",
"createdAt": ISODate("2021-01-03T09:31:43.263Z")
}
{
"_id": ObjectId("5ff18eff9d594f01396c9ea8"),
"content": "机械日志1",
"createdAt": ISODate("2021-01-03T09:31:43.275Z")
}
// ... 隐藏其他数据
5分钟后查看数据:
> db.machineLog.find()
修改
对于TTL索引的expireAfterSeconds的属性,可以用collMod方式进行修改>
重新写入数据:
> for (i = 0; i < 10; i++) {
db.machineLog.insert({
"content": "机械日志" + i,
"createdAt": new Date()
})
}
创建索引:
> db.machineLog.createIndex({createdAt:1}, {expireAfterSeconds:300})
查看索引:
[
{
"v": NumberInt("2"),
"key": {
"_id": NumberInt("1")
},
"name": "_id_",
"ns": "machine.machineLog"
},
{
"v": NumberInt("2"),
"key": {
"createdAt": 1
},
"name": "createdAt_1",
"ns": "machine.machineLog",
"expireAfterSeconds": 300
}
]
修改TTL索引:
> db.runCommand({
collMod: "machineLog",
index: {
keyPattern: {
createdAt: 1
},
expireAfterSeconds: 60
}
})
重新查看索引信息:
[
{
"v": NumberInt("2"),
"key": {
"_id": NumberInt("1")
},
"name": "_id_",
"ns": "machine.machineLog"
},
{
"v": NumberInt("2"),
"key": {
"createdAt": 1
},
"name": "createdAt_1",
"ns": "machine.machineLog",
"expireAfterSeconds": 60
}
]
网友评论