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文档中没看到说有这种限制啊

64位错误

connecting to: localhost/test

tcmalloc: 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

回到顶部