当前位置: 首页 > 知识库问答 >
问题:

如果封顶集合达到最大大小,为什么MongoDB不会删除旧文档?

濮君植
2023-03-14

我有一个有上限的集合,它是在java代码中创建的:

this.collection = db.createCollection("stat", new BasicDBObject("capped", true).append("size", 200000000).append("max", 1000000));

现在在这个集合的统计数据中,我们有:

/* 0 */
{
    "ns" : "myDatabase.stat",
    "count" : 12212,
    "size" : 2146416,
    "avgObjSize" : 175,
    "storageSize" : 200003584,
    "numExtents" : 1,
    "nindexes" : 4,
    "lastExtentSize" : 200003584,
    "paddingFactor" : 1,
    "systemFlags" : 1,
    "userFlags" : 0,
    "totalIndexSize" : 2272928,
    "indexSizes" : {
        "_id_" : 1259104,
        "downloaded_1" : 335216,
        "submitted_1" : 318864,
        "retries_1" : 359744
    },
    "capped" : true,
    "max" : 1000000,
    "ok" : 1
}

如果我尝试使用此代码插入集合中的文档:

BasicDBObject doc = new BasicDBObject().
        append("downloaded", new Date(0)).
        append("sessionId", sessionId).
        append("group", group);
collection.update(new BasicDBObject("_id", request.getUrl()), new BasicDBObject("$set", doc), true, false);

我发现了这个错误:

com.mongodb.WriteConcernException: { "serverUsed" : "/127.0.0.1:27017" , "lastOp" : { "$ts" : 0 , "$inc" : 0} , "connectionId" : 16420 , "err" : "failing update: objects in a capped ns cannot grow" , "code" : 10003 , "n" : 0 , "ok" : 1.0}
        at com.mongodb.CommandResult.getException(CommandResult.java:77)
        at com.mongodb.CommandResult.throwOnError(CommandResult.java:110)
        at com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:102)
        at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:142)
        at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:115)
        at com.mongodb.DBApiLayer$MyCollection.update(DBApiLayer.java:327)
        at com.mongodb.DBCollection.update(DBCollection.java:178)
        at com.mongodb.DBCollection.update(DBCollection.java:209)
        at com.srg.hydra.monitoring.HydraStatistics.insert(HydraStatistics.java:63)
        at com.srg.hydra.HydraSite.onSubmit(HydraSite.java:91)
        at ru.decipher.site.AbstractSite.submit(AbstractSite.java:198)
        at com.srg.hydra.Eip.start(Eip.java:48)
        at com.srg.hydra.runner.DefaultHydraRunner.doCrawling(DefaultHydraRunner.java:180)
        at com.srg.hydra.runner.DefaultHydraRunner$1.run(DefaultHydraRunner.java:155)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)

我做错了什么?如何修复它?(排除到. down()此集合并重新创建)感谢您的回答!

共有1个答案

奚光霁
2023-03-14

您不能更新封顶集合中的文档。(如果你阅读了我的全部答案,你会发现有一些解决办法)。我过去也经历过这个问题。请从下面的MongoDB文档中查找此问题的详细信息(和解决方案):

建议和限制

>

如果计划更新封顶集合中的文档,请创建索引,以便这些更新操作不需要扫描表。

如果将封顶集合中的文档更新为小于其原始大小的大小,然后从主文档重新同步辅助文档,则辅助文档将根据当前较小的文档大小复制和分配空间。如果主系统随后收到一个更新,将文档增加回其原始大小,则主系统将接受更新,但次系统将因更新失败而失败:封顶ns中的对象无法增长错误消息

要防止此错误,请从副本集的另一个最新成员的快照创建辅助副本。按照我们关于文件系统快照的教程,为您的新辅助系统添加种子。

使用文件系统快照为辅助文件设定种子是确保主二进制文件和辅助二进制文件兼容的唯一方法。在这种情况下,MMS备份快照是不够的,因为要匹配主备份快照,您需要的不仅仅是辅助备份快照的内容。

您不能从封顶集合中删除文档。要删除封顶集合中的所有记录,请使用“emptycapped”命令。要完全删除集合,请使用drop()方法。

你不能分割封顶的收藏。

默认情况下,在2.2之后创建的封顶集合具有_id字段和_id字段上的索引。默认情况下,2.2之前创建的封顶集合在_id字段上没有索引。如果在2.2之前的复制中使用capped collections,那么应该在_id字段上显式创建索引。

 类似资料:
  • 当我试图在MongoDB中删除集合中的文档时。它没有删除,因为集合已被封顶。我的问题是为什么?在这种情况下,是否有解决方案或其他功能可以删除文档?

  • 我在三个EC2实例中有一个MongoDB客户机,并创建了一个副本集。上一次我遇到了一个问题,空间限制导致mongod进程停止,从而使应用程序停止,现在在几天前的一个实例中,我的一些表从数据库中消失了,所以我将日志记录和所有设置到数据库中,以便捕捉再次发生类似情况的情况。在今天早上的一个新事件中,我无法登录到我的系统,这时我发现整个数据库都是空的。我检查了其他类似这样的问题,建议设置TTL.,但我根

  • 假设我有32 GB的RAM,我通过指定-xmx2048m为我的java进程分配了2GB。但实际上我的进程通常只消耗1GB的堆。那么分配的剩余1GB内存会发生什么呢?剩余的RAM总量是30 GB还是31 GB?

  • 问题内容: 有什么办法可以设置Java的最大集合大小? 问题答案: 你可以这样做: 结果列表是可修改的,但不可调整大小(即,虽然不起作用,但可以)。 参考: 或者:使用Guava,这是一个静态方法,该方法以最大大小装饰现有的List 由于Forw​​ardingXxx类适用于所有标准集合类型,因此您也可以为其他集合编写类似的修饰符。 显然,这仅在您的客户端代码使用修饰的集合时才有效。如果更改基础集

  • 在 MongoDB 中,可以使用 drop() 方法来从数据库中删除指定集合,它会从数据库中完全删除一个集合,并且不会留下与已删除集合关联的任何索引。 drop() 方法在使用时不需要带有任何参数,并且在使用参数调用时会产生错误,该方法的语法格式如下: db.collection_name.drop() 其中 collection_name 为要删除的集合名称,方法调用成功会返回 true,否则返

  • 问题内容: 在采访中问。如果指定最大堆大小(Xmx)大于可用RAM,会发生什么情况?我还想知道,如果指定最小堆大小(Xms)大于可用RAM,会发生什么情况? 问题答案: 找出答案的最简单方法是尝试并查看。 编辑: 实际上至少有两个答案。如前所述,可能是在64位系统上,您的应用程序的内存使用量可能会越来越大,并且开始崩溃。在32位系统上,情况有所不同,因为os无法为您提供那么多的堆空间。例如,如果我