将数据写入Mongo的“本地”数据库时是否需要考虑其他因素?

时间:2014-01-25 00:23:04

标签: mongodb local-database

编辑: 这里有几点观点

写入“本地”是一种合法的技术 - 来自“MongoDB:The Definitive Guide,2nd.ED”和http://www.kchodorow.com/blog/2010/10/27/bending-the-oplog-to-your-will/

  

此数据库永远不会被复制,可用于存储任何数据库   应该是单个服务器本地的集合

写入“本地”绝不是一个好主意 - 来自https://jira.mongodb.org/browse/SERVER-11670https://groups.google.com/forum/#!topic/mongodb-user/E_aPgNR1zss

  

将任何内容写入本地数据库是不行的 - 它适用于   MongoDB使用它并将其用于用户集合(以避免复制   他们不保证不会引起问题

这可能是也可能不是一个好主意 - http://docs.mongodb.org/manual/reference/local-database/上的文档是不可知的


原帖:

我在Mongo 2.4.9安装(Windows和Linux版本)上向“本地”数据库写入大约100MB数据时遇到错误。

这个错误(https://jira.mongodb.org/browse/SERVER-11670)看起来与我的问题类似,但我无法相信随机写入数据库失败是一个小问题,它将推迟到2.7。所以必须是我。

无论如何,Windows错误看起来像这样:

Fri Jan 24 15:59:11.551 [conn40] mongod.exe    ...\src\mongo\util\stacktrace.cpp(167)                           mongo::printStackTrace+0x3e
Fri Jan 24 15:59:11.551 [conn40] mongod.exe    ...\src\mongo\db\dur.cpp(277)                                    mongo::dur::DurableImpl::_aCommitIsNeeded+0xe8
Fri Jan 24 15:59:11.551 [conn40] mongod.exe    ...\src\mongo\db\instance.cpp(812)                               mongo::insertMulti+0x212
Fri Jan 24 15:59:11.551 [conn40] mongod.exe    ...\src\mongo\db\instance.cpp(875)                               mongo::receivedInsert+0xaff
Fri Jan 24 15:59:11.552 [conn40] mongod.exe    ...\src\mongo\db\instance.cpp(441)                               mongo::assembleResponse+0x57a
Fri Jan 24 15:59:11.552 [conn40] mongod.exe    ...\src\mongo\db\db.cpp(194)                                     mongo::MyMessageHandler::process+0xfa
Fri Jan 24 15:59:11.552 [conn40] mongod.exe    ...\src\mongo\util\net\message_server_port.cpp(207)              mongo::PortMessageServer::handleIncomingMsg+0x578
Fri Jan 24 15:59:11.552 [conn40] mongod.exe    ...\src\third_party\boost\libs\thread\src\win32\thread.cpp(180)  boost::`anonymous namespace'::thread_start_function+0x21
Fri Jan 24 15:59:11.552 [conn40] mongod.exe    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\threadex.c(314)      _callthreadstartex+0x17
Fri Jan 24 15:59:11.552 [conn40] mongod.exe    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\threadex.c(292)      _threadstartex+0x7f
Fri Jan 24 15:59:11.553 [conn40] kernel32.dll                                                                   BaseThreadInitThunk+0xd
Fri Jan 24 15:59:11.553 [conn40] ERROR: can't commitNow from commitIfNeeded, as we are in local db lock

Linux错误看起来像这样:

Sat Jan 25 00:20:04.558 [conn19] ERROR: can't commitNow from commitIfNeeded, as we are in local db lock
0xde46e1 0x921a65 0x921b4c 0x9f8b15 0x9f9412 0x9ffd68 0x6e8518 0xdd0cae 0x7f0cd72d8ddb 0x7f0cd667ca1d
 /usr/bin/mongod(_ZN5mongo15printStackTraceERSo+0x21) [0xde46e1]
 /usr/bin/mongod(_ZN5mongo3dur11DurableImpl16_aCommitIsNeededEv+0x155) [0x921a65]
 /usr/bin/mongod(_ZN5mongo3dur11DurableImpl14commitIfNeededEb+0x4c) [0x921b4c]
 /usr/bin/mongod(_ZN5mongo11insertMultiEbPKcRSt6vectorINS_7BSONObjESaIS3_EERNS_5CurOpE+0x45) [0x9f8b15]
 /usr/bin/mongod(_ZN5mongo14receivedInsertERNS_7MessageERNS_5CurOpE+0x862) [0x9f9412]
 /usr/bin/mongod(_ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE+0xab8) [0x9ffd68]
 /usr/bin/mongod(_ZN5mongo16MyMessageHandler7processERNS_7MessageEPNS_21AbstractMessagingPortEPNS_9LastErrorE+0x98) [0x6e8518]
 /usr/bin/mongod(_ZN5mongo17PortMessageServer17handleIncomingMsgEPv+0x42e) [0xdd0cae]
 /lib64/libpthread.so.0(+0x7ddb) [0x7f0cd72d8ddb]
 /lib64/libc.so.6(clone+0x6d) [0x7f0cd667ca1d]

错误是间歇性的,但通常在块中发生30-90秒,在此期间我无法写入任何数据。有几次我不得不杀死写入数据的进程。

说到数据,我正在写大约750,000个相当简单的文档(一些字符串和一个小的嵌入式文档)。没有用户指定的索引,只是_id上的默认索引。

我可以期待写入“本地”数据库而不会出错吗?我读到这是一种合法的数据技术,你不想复制它。

这有什么变通方法吗?特殊配置设置?我正在使用Windows安装的默认配置和Linux安装的轻微日志修改

2 个答案:

答案 0 :(得分:0)

你是在副本集中运行吗?如果是这样,您看到写入被阻止的原因是所有其他线程需要写入oplog,这需要获取本地数据库上的写锁定。

读取代码时,如果未提交的数据量超过某个阈值,MongoDB将尝试在插入线程上提交数据,但如果您使用的是本地数据库或管理数据库,则不会这样做。因此,当您反复尝试写入本地数据库并且MongoDB希望插入线程提交数据时,执行这些本地数据库写入的线程可能会崩溃。

假设你有其他线程正在进行写操作,我认为可能的解决方法是在你收到此错误时暂停一小段时间,让另一个线程有机会在不保留本地数据库的情况下提交日志。但这是阅读代码的猜测。

答案 1 :(得分:0)

local数据库仅用于MongoDB复制和其他内部跟踪。

根据Asya对SERVER-11670的评论:

  

无论这个票据是什么,都不能写任何东西到本地数据库 - 它是用于MongoDB的使用并将其用于用户集合(以避免复制它们)不能保证不会引起问题(除了这个问题你已经碰到了。“。

在本期中,她正在针对oplog测试聚合的新$out功能,这就是受影响的版本为2.5.3(开发/不稳定)并且fixVersion不确定的原因。

如果要编写不会复制的数据,最好的方法是设置一个单独的mongod实例。 (在MongoDB 2.4中)没有一种支持的方法可以在副本集部署中存储您自己的非复制数据。