通过设置 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值必须在02147483647包含在内。

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 索引,指定expireAfterSeconds0。对于集合中的每个文档,将索引日期字段设置为与文档到期时间相对应的值。如果索引日期字段包含过去的日期,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 索引设置为 时expireAfterSecondsNaNMongoDB 会记录错误并且不会删除任何记录。

从 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 索引。

  1. 识别配置错误的索引

    在中运行以下脚本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();
    
  2. 纠正错误配置的索引

    使用该collMod命令更新 expireAfterSeconds脚本发现的任何配置错误的值。

    作为替代方案,您可以drop使用命令来重新创建任何配置错误的 TTL 索引 createIndexes

Copyright © 上海锦木信息技术有限公司 all right reserved,powered by Gitbook文件修订时间: 2023-09-01 17:10:26

results matching ""

    No results matching ""