我在Windows平台,64位,16GB RAM(以及使用C#mongodb驱动程序)上使用MongoDB
版本2.6.1。
在我的环境中,我每隔10秒插入约15个文档(每个文档最多128B)。每个插入操作都插入一个文档,目前在我的(单个)集合中,我获得了621,000个文档
最近,我发现了"漏洞"在所有插入中几分钟。当我说" hole"我的意思是在同一时间范围内没有插入任何文件。
要进行调试,我在每次插入后打印WriteConcernResult
,令人惊讶的是,查询中缺少的所有插入文档都已成功插入:
WriteConcertResult: writeResult.Ok - True, writeResult.HasLastErrorMessage - False, writeResult.LastErrorMessage - , writeResult.ErrorMessage - , writeResult.Response - { "connectionId" : 57, "n" : 0, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1.0 }
为了确保我在失败时应该得到例外,我插入了两次相同的文件
现在它只是让事情变得更有意义,因为我确实遇到了重复键错误,但仍然无法找到该文档。
并确保我没有"查询"问题我检查了是否有任何文件被添加到集合中时,我抓住了这个洞"在行为"我发现没有添加任何内容(即使写入问题结果为Ok)。
然后我转向mongo log(我用-vvvvv开始)并且我找不到任何太可疑的东西:
2014-07-07T19:34:01.393+0300 [journal] journal REMAPPRIVATEVIEW
2014-07-07T19:34:01.393+0300 [journal] journal REMAPPRIVATEVIEW done startedAt: 5 n:4 0ms
2014-07-07T19:34:01.393+0300 [journal] groupCommit end
2014-07-07T19:34:02.219+0300 [conn8] PageFaultException thrown
2014-07-07T19:34:02.219+0300 [conn8] insert myDb.files ninserted:1 keyUpdates:0 numYields:0 locks(micros) w:120 0ms
2014-07-07T19:34:02.219+0300 [conn8] run command myDb.$cmd { getlasterror: 1 }
2014-07-07T19:34:02.219+0300 [conn8] command myDb.$cmd command: getLastError { getlasterror: 1 } ntoreturn:1 keyUpdates:0 numYields:0 reslen:94 0ms
2014-07-07T19:34:02.219+0300 [conn8] run command myDb.$cmd { findAndModify: "reposInfo", query: { RepositorySizeInBytes: { $exists: true } }, update: { $inc: { RepositorySizeInBytes: 1018460 } }, new: true }
2014-07-07T19:34:02.219+0300 [conn8] Only one plan is available; it will be run but will not be cached. query: { RepositorySizeInBytes: { $exists: true } } sort: {} projection: {}, planSummary: COLLSCAN
2014-07-07T19:34:02.219+0300 [conn8] processing update : query: { _id: ObjectId('538760d681536a0414a23bc9') } updated: { $inc: { RepositorySizeInBytes: 1018460 } } god: 0 upsert: 0 multi: 0 callLogOp: 1 fromMigration: 0 fromReplications: 0
2014-07-07T19:34:02.219+0300 [conn8] Using idhack: { _id: ObjectId('538760d681536a0414a23bc9') }
2014-07-07T19:34:02.219+0300 [conn8] update validate options -- updatedFields: Fields:[ RepositorySizeInBytes,] immutableAndSingleValueFields.size:0 fromRepl: 0 validate:1
2014-07-07T19:34:02.219+0300 [conn8] UpdateResult -- upserted: {} modifiers: 1 existing: 1 numDocsModified: 1 numMatched: 1
2014-07-07T19:34:02.219+0300 [conn8] update result: upserted: {} modifiers: 1 existing: 1 numDocsModified: 1 numMatched: 1
2014-07-07T19:34:02.219+0300 [conn8] using modified query to return the new doc: { _id: ObjectId('538760d681536a0414a23bc9') }
2014-07-07T19:34:02.219+0300 [conn8] Using idhack: query: { _id: ObjectId('538760d681536a0414a23bc9') } sort: {} projection: {}
2014-07-07T19:34:02.219+0300 [conn8] command myDb.$cmd command: findAndModify { findAndModify: "reposInfo", query: { RepositorySizeInBytes: { $exists: true } }, update: { $inc: { RepositorySizeInBytes: 1018460 } }, new: true } update: { $inc: { RepositorySizeInBytes: 1018460 } } ntoreturn:1 nscanned:1 nscannedObjects:1 nMatched:1 nModified:1 fastmod:1 keyUpdates:0 numYields:0 locks(micros) w:215 reslen:144 0ms
我不确定是否会抛出" PageFaultException" part与问题有关,但在阅读了这个异常之后,我明白这可能是正常的,然后我在实际成功插入之前也看到了这个例外,所以我继续这样做。
即使写入问题结果告诉我一切正常,我仍然检查serverStatus
和currentOp
是否有可能的锁定操作,但是在那里找不到任何奇怪的东西。
关于如何更好地调试这种情况的建议?
无聊的信息:
- 使用new MongoClient(addr)
>创建mongodb实例client.GetServer()
> server.GetDatabase(dbName)
(因此默认情况下启用了写入关注)
- 该系列完全标准(不是上限系列,没有分片,没有副本)
- 用于插入文档的_id是BinData
- mongo进程占用(根据任务管理器)38,148K RAM,只有20%的服务器RAM正在使用中。
- mongo版本已更新,为64位。
- 更新 -
当我通过BinData _id搜索文档时,我可以(以某种方式)获取它,但它可以通过任何其他方式隐藏。
例如,当我搜索这个时:
db.files.find({"_id": BinData(0, "alnYNFB8XxGo+KB8A70vCw==")})
我得到(第一个对象):
{
"_id" : BinData(0,"alnYNFB8XxGo+KB8A70vCw=="),
"dId" : "537cbafd81536a0aa03f6be3",
"cN" : 1,
"ty" : 0,
"sT" : ISODate("2014-07-08T06:53:20.534Z"),
"eT" : ISODate("2014-07-08T06:53:30.845Z"),
"hS" : 40,
"sId" : 1
}
但是当我搜索" sT"时,我发现没有(当我通过&#34执行相同的搜索; sT"对于我在集合中看到的文档,我可以找到它们)。
什么da ...
- 更新(对Asya的评论) -
搜索" sT" " good"的例子文件:
>> goodDate = ISODate("2014-07-08T06:55:59.056Z");
>> db.files.find({"sT": goodDate})
我收到了退回的文件。然后我做:
>> missDate = ISODate("2014-07-08T06:53:20.534Z")
>> db.files.find({"sT": missDate})
一无所获!
另一个例子:
>> db.files.find({"sT": {$gte: missDate}})
第一个结果从" sT&#34开始; :ISODate("2014-07-08T06:55:41.446Z")
db.files.find().length()
并且它是相同的。 - 更新 -
经过一些测试(感谢mongo论坛),我们认为这个问题应该作为一张票
所以在mongo r& d社区发布了一张票。当我们确切知道发生了什么时,我会继续并在此更新。