MongoDB: 插入数据时报错,terminate called in shell()
处理的是一个.js文件,中间包含大量insert命令和update命令。一个命令占一行。
文件大小为222M.
错误信息如下:
我猜测可能是因为单条命令太长的缘故,但是用mongo直接处理.js文件按理说不会有这样的问题才对吧
系统是debian 32位,版本2.6.32-5-386
在stackoverflow和segmentfault找,也只看到有人遇到堆栈信息中是_ZN5开头的。
在64位mongodb上运行成功了。
但是64位加载2.3G文件的时候又有错误,好在这次有明确信息了。
拆成200多M的文件就能处理了。
很奇怪,我在mongodb文档中没看到说有这种限制啊
connecting to: localhost/testtcmalloc: large alloc 2364833792 bytes == 0x2658000 @
2014-08-19T21:49:28.069-0400 Assertion: 16569:In File::read(), ::pread for 'univ100-100.js' read 2147479552 bytes while trying to read 2364826029 bytes starting at offset 0, truncated file?
2014-08-19T21:49:28.164-0400 0x864f81 0x813579 0x7f6f86 0x7f74dc 0x80a61f 0x79781d 0x61f12a 0x621f63 0x3ff161ecdd 0x61a049
mongo(_ZN5mongo15printStackTraceERSo+0x21) [0x864f81]
mongo(_ZN5mongo10logContextEPKc+0x159) [0x813579]
mongo(_ZN5mongo11msgassertedEiPKc+0xe6) [0x7f6f86]
mongo() [0x7f74dc]
mongo(_ZN5mongo4File4readEmPcj+0x30f) [0x80a61f]
mongo(_ZN5mongo5Scope8execFileERKSsbbi+0x61d) [0x79781d]
mongo(_Z5_mainiPPcS0_+0x52a) [0x61f12a]
mongo(main+0x33) [0x621f63]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x3ff161ecdd]
mongo(__gxx_personality_v0+0x469) [0x61a049]
exception: In File::read(), ::pread for 'univ100-100.js' read 2147479552 bytes while trying to read 2364826029 bytes starting at offset 0, truncated file?
real 0m7.922s
user 0m0.045s
sys 0m2.477s
回答:
非常感谢你的报告。
首先,stack trace是gcc mangle过的,可以用 demangler 反过来看到。
假设你的server跟shell一样是2.6.3, 问题直接出在这里,shell会把整个script文件读入内存然后编译,2.3G的文件在32位机器上有问题就可以解释了。但是在64位机器上也会出问题就不应该了。
这里有两个问题。
1. 应该限制JS文件大小为 2G 以兼容32位操作系统。现在的逻辑正确,但是上限太大了,与描述不符。
2. 在读文件时,系统不总能保证一次pread
调用读完,所以在 file.cpp 中最好多次读取,直至结束或错误。
希望我把问题讲明白了。临时办法是如你所做,把文件分成小份。如果你能在 Jira 中提交这一问题就再好不过了,用英语简单地描述你遇到的问题就好了。Kernel工程师会在以后的开发中改进,你也可以在Jira上跟踪这一问题。如果你不方便,我可以帮你来提交。
更好的办法是在Jira上提交报告之后,到 Github 上 fork MongoDB的代码,修改然后提交 Pull Request,由 Kernel 工程师进行 code reivew, 最终合并进代码库里。因为这个问题比较罕见,相对独立,又比较清晰,很适合作为小任务完成后提交Pull Request。然后全世界的 MongoDB 用户都运行着你写的代码啦。我觉得既然MongoDB中国用户这么多,我们有能力为MongoDB社区贡献力量。如果还有什么问题就跟我说。
P.S. 我很好奇你为什么需要一个2.3G的脚本,如果能告诉我你要做的事情,可能有更优雅的解决方案。
以上是 MongoDB: 插入数据时报错,terminate called in shell() 的全部内容, 来源链接: utcz.com/p/197049.html