通过设置 TTL 使集合中的数据过期
本文档介绍了 MongoDB 的“生存时间”或TTL收集功能。TTL 集合可以将数据存储在 MongoDB 中,并mongod
在指定的秒数或特定的时钟时间后自动删除数据。
数据过期对于某些类别的信息很有用,包括机器生成的事件数据、日志和仅需要保留一段有限时间的会话信息。
特殊的TTL 索引属性支持 TTL 集合的实现。TTL 功能依赖于后台线程,mongod
该线程读取索引中的日期类型值并从集合中删除过期文档。
要创建 TTL 索引,请使用createIndex()
. 指定索引字段,该索引字段可以是日期类型,也可以是包含日期类型值的数组。使用该expireAfterSeconds
选项指定 TTL 值(以秒为单位)。
笔记:
TTL索引是单字段索引。复合索引不支持 TTL 属性。有关 TTL 索引的更多信息,请参阅 TTL 索引。
您可以expireAfterSeconds
使用该命令修改现有 TTL 索引collMod
。
指定秒数后使文档过期
要在自索引字段经过指定秒数后使数据过期,请在保存 BSON 日期类型值或 BSON 日期类型对象数组的字段上创建 TTL 索引,并在字段中指定正expireAfterSeconds
非零值。expireAfterSeconds
当自其索引字段中指定的时间起经过该字段中的 秒数时,文档将过期。[ 1 ]
TTL 索引expireAfterSeconds
值必须在0
且 2147483647
包含在内。
log_events
例如,以下操作在集合的字段上创建索引 createdAt
,并指定 expireAfterSeconds
的值,10
将过期时间设置为 指定的时间后十秒createdAt
。
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 10 } )
将文档添加到log_events
集合时,将 createdAt
字段设置为当前时间:
db.log_events.insertOne( {
"createdAt": new Date(),
"logEvent": 2,
"logMessage": "Success!"
} )
log_events
当文档的createdAt
值 [ 1 ]早于指定的秒数时,MongoDB将自动从集合中删除文档expireAfterSeconds
。
[ 1 ] | ( 1 , 2 ) 如果字段包含一组 BSON 日期类型对象,则如果至少一个 BSON 日期类型对象早于 中指定的秒数,则数据将过期 expireAfterSeconds 。 |
---|---|
文档在特定时钟时间过期
要在特定时钟时间使文档过期,请首先在保存 BSON 日期类型值或 BSON 日期类型对象数组的字段上创建 TTL 索引,并指定expireAfterSeconds
值0
。对于集合中的每个文档,将索引日期字段设置为与文档到期时间相对应的值。如果索引日期字段包含过去的日期,MongoDB 会认为该文档已过期。
log_events
例如,以下操作在集合的字段上创建索引 expireAt
并指定 expireAfterSeconds
的值0
:
db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
对于每个文档,设置 的值expireAt
以对应于文档应过期的时间。例如,以下 insertOne()
操作添加一个到期时间为 的文档July 22, 2013 14:00:00
。
db.log_events.insertOne( {
"expireAt": new Date('July 22, 2013 14:00:00'),
"logEvent": 2,
"logMessage": "Success!"
} )
log_events
当文档的expireAt
值早于 中指定的秒数expireAfterSeconds
(在本例中即早几秒)时,MongoDB 将自动从集合中删除文档0
。因此,数据在指定 expireAt
值处过期。
使用 NaN 配置的索引
警告
可能的数据丢失
当 TTL 索引
expireAfterSeconds
设置为 时NaN
,升级、降级和某些同步操作可能会导致意外行为并可能导致数据丢失
不要在 TTL 索引配置中设置expireAfterSeconds
为。NaN
在 MongoDB 5.0 之前,当 TTL 索引设置为 时expireAfterSeconds
, NaN
MongoDB 会记录错误并且不会删除任何记录。
从 MongoDB 5.0.0 - 5.0.13(和 6.0.0 - 6.0.1),NaN
被视为 0
. 如果 TTL 索引配置为expireAfterSeconds
设置为 NaN
,则所有 TTL 索引的文档都会立即过期。
从 MongoDB 5.0.14(和 6.0.2)开始,服务器将不再使用expireAfterSeconds
设置为 的TTL 索引NaN
。
但是,仍有一些情况可能会导致意外行为。文件可能会过期:
- 在从 MongoDB 5.0.0 - 5.0.13(或 6.0.0 - 6.0.1)初始同步到早期版本期间。
- 从早期版本升级到 MongoDB 5.0.0 - 5.0.13 时。
- 从 5.0 之前的版本恢复集合时
mongodump
到 MongoDB 5.0.0 - 5.0.13(或 6.0.0 - 6.0.1)实例。
为了避免出现问题,请删除或更正任何配置错误的 TTL 索引。
识别配置错误的索引
在中运行以下脚本
mongosh
壳。该脚本在旧 shell 中不起作用mongo
。function getNaNIndexes() { const nan_index = []; const dbs = db.adminCommand({ listDatabases: 1 }).databases; dbs.forEach((d) => { const listCollCursor = db .getSiblingDB(d.name) .runCommand({ listCollections: 1 }).cursor; const collDetails = { db: listCollCursor.ns.split(".$cmd")[0], colls: listCollCursor.firstBatch.map((c) => c.name), }; collDetails.colls.forEach((c) => db .getSiblingDB(collDetails.db) .getCollection(c) .getIndexes() .forEach((entry) => { if (Object.is(entry.expireAfterSeconds, NaN)) { nan_index.push({ ns: `${collDetails.db}.${c}`, index: entry }); } }) ); }); return nan_index; }; getNaNIndexes();
纠正错误配置的索引
使用该
collMod
命令更新expireAfterSeconds
脚本发现的任何配置错误的值。作为替代方案,您可以
drop
使用命令来重新创建任何配置错误的 TTL 索引createIndexes
。