【问题标题】:MongoDB expireAfterSeconds / TTL is not deleting data in existing collectionMongoDB expireAfterSeconds / TTL 未删除现有集合中的数据
【发布时间】:2016-02-13 15:29:24
【问题描述】:

我有一个包含现有数据的集合。我使用 expireAfterSeconds 参数向这个集合添加了一个新索引:

2015-11-11T09:09:21.565+0100 I INDEX    [conn120] build index on: cmon.cmon.interfaces_history properties: { v: 1, key: { expireAt: 1 }, name: "expireAt_1", ns: "cmon.cmon.interfaces_history", expireAfterSeconds: 1 }
2015-11-11T09:09:21.565+0100 I INDEX    [conn120]    building index using bulk method
2015-11-11T09:09:21.730+0100 I INDEX    [conn120] build index done.  scanned 8933 total records. 0 secs
2015-11-11T09:09:21.733+0100 I COMMAND  [conn120] command cmon.$cmd command: createIndexes { createIndexes: "cmon.interfaces_history", indexes: [ { expireAfterSeconds: 1, name: "expireAt_1", key: { expireAt: 1 } } ] } keyUpdates:0 writeConflicts:0 numYields:0 reslen:113 locks:{ Global: { acquireCount: { r: 1, w: 1 } }, MMAPV1Journal: { acquireCount: { w: 17870 }, acquireWaitCount: { w: 1 }, timeAcquiringMicros: { w: 886 } }, Database: { acquireCount: { W: 1 } }, Collection: { acquireCount: { W: 1 } }, Metadata: { acquireCount: { W: 2 } } } 169ms

然后我添加了一个新条目,其 expireAt 值设置如下:

{
"_id" : ObjectId("56446521637140e419b881c7"),
"DeviceName" : "mx1",
"updateTime" : ISODate("2015-11-05T11:17:10.000Z"),
"expireAt" : ISODate("2015-11-12T11:10:13.257Z"),
"DomainName" : "domain.net",
"ifAdminStatus" : "up",
"ifName" : "3002",
"ifOperStatus" : "up"
}

此集合中的现有条目看起来完全相同,但没有设置 expireAt。 MongoDB 不会从数据库中删除此条目。当我 在一个空的集合和测试数据库上对其进行了测试。

> db.serverStatus().metrics.ttl
{ "deletedDocuments" : NumberLong(0), "passes" : NumberLong(823) }

所以我怀疑它不会删除这个条目,因为集合中还有其他条目没有这个字段。还是有其他问题?

【问题讨论】:

  • 这不是 TTL 索引和删除的工作方式。它实际上是索引中的属性集,基于从文档中存在的指定日期字段(和索引字段)经过的设定时间段。见documentation
  • @BlakesSeven 好吧,根据 OP 所附的日志,他确实遵循了文档。 { expireAfterSeconds: 1, name: "expireAt_1", key: { expireAt: 1 } }。您似乎没有仔细阅读问题。
  • @DmytroShevchenko 看起来 OP 和您自己没有正确阅读文档,因为 TTL 进程仅“每 60 秒运行一次”,因此最多允许两分钟进行实际删除。指定的 1 秒明确表示该文档预计将被立即删除,这与所有说不是的文档形成鲜明对比。因此,这不是一个经过充分研究的问题。
  • @falc410 您在插入文档后尝试等待多长时间?请阅读以下内容:docs.mongodb.org/v3.0/core/index-ttl — 删除文档的后台线程每 60 秒运行一次,因此为了确保您的方法不起作用,请尝试等待几分钟。
  • 我已阅读文档并在另一个数据库上对其进行了测试,并按预期执行。是的,我希望在命中 expireAt 值后立即删除该条目。根据文档,我可以使用 expireAfterSeconds: 0 创建索引,但这似乎不起作用,所以我使用 expireAfterSeconds: 1

标签: mongodb


【解决方案1】:
"expireAt" : ISODate("2015-11-12T11:10:13.257Z")

您指定的到期日期和时间是将来的。截至本答案发布时,到期将在两分钟后发生。这就是为什么该文档仍未从您的收藏中删除的原因。但很快就会被删除。

您指定的日期/时间格式末尾有一个Z,它强制执行 UTC 时区。

【讨论】:

  • 谢谢,你是对的。即使我在本地运行 mongoDB 和我的 Python 代码并使用 datetime.datetime.now() + datetime.timedelta(seconds=60) 设置 expireAt 值,它实际上不是使用我的系统时间而是使用 UTC 时区创建的 datetime 对象。跨度>
  • @falc410 很高兴能帮上忙!
  • @VivekSingh 您的评论完全超出了问题的范围。请为此创建一个单独的问题。
  • 我对 UTC 有同样的问题,如何解决?需要在机器时间过期
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 2013-09-14
相关资源
最近更新 更多