MongoDB-PHP-MongoCursorException'未找到游标' [英] MongoDB - PHP - MongoCursorException 'Cursor not found'

查看:67
本文介绍了MongoDB-PHP-MongoCursorException'未找到游标'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个收藏集:A(380万个文档)和B(170万个文档)

I have 2 collections: A (3.8M docs) and B (1.7M docs)

我有一个从外壳运行的PHP脚本:

I have a PHP script that I run from the shell that:

  1. 遍历A中的每个记录
  2. 〜60%的时间,它在B上执行一次findOne(使用_id)
  3. 做一些基本的数学运算,创建一个php数组

一次完成所有文档上的循环:

once the loop on all docs in a is done:

4)遍历php数组

5)向上添加到集合C

5)upsert into collection C

在(1)期间,我始终得到:PHP致命错误:未捕获的异常'MongoCursorException'和消息'未找到游标' 最后处理的项目是3872494中的第8187个.

during (1), I consistently get: PHP Fatal error: Uncaught exception 'MongoCursorException' with message 'Cursor not found' The last item processed was #8187 of 3872494.

real    1m25.478s
user    0m0.076s
sys     0m0.064s

再次运行它,而无需更改代码,该异常引发于项目#19826/3872495

Running it again, with no change in code, the exception got thrown at item #19826 / 3872495

real    3m19.144s
user    0m0.120s
sys     0m0.072s

再次,#8181/387249

And again, #8181 / 387249

real    1m31.110s
user    0m0.036s
sys     0m0.048s

是的,我意识到我可以(也许应该)捕获异常……但是……为什么还要抛出该异常?特别是在进入数据库的时间/深度如此不同的情况下.

Yes, I realize that I can (and probably should) catch the exception... but... why is it even being thrown? Especially at such different elapsed time/depth into the database.

如果有帮助,我的设置是一个3节点副本集(2 + arb).我使次要服务器脱机,并尝试仅使主要服务器运行.结果相同(处理的结果数量和时间不同,但始终会引发未找到游标"异常).

If it helps, my setup is a 3-node replica set (2+arb). I took the secondary offline and tried with just the primary running. Same results (different number of results processed and times, but always throws the Cursor Not Found exception).

推荐答案

是的,我意识到我可以(也许应该)捕获异常...

Yes, I realize that I can (and probably should) catch the exception...

是的,这绝对是第一件事.有数十种合理的理由导致例外发生?哎呀,当主节点脱机并变得不可达时,您会怎么想?

Yes, this is definitely the first thing to do. There are dozens of legitimate reasons for an exception to happen? Heck what do you think happens when the primary goes off-line and becomes unreachable?

...为什么还要扔呢?

... why is it even being thrown?

有两个可能的原因,但让我们直接看一下您看到的错误代码.

There are a couple of potential reasons, but let's cut straight to the error code you're seeing.

  • 官方PHP文档位于此处.
  • 该页面的报价:驱动程序试图从数据库中获取更多结果,但是数据库没有查询记录.这通常意味着光标在服务器端超时...
  • Official PHP docs are here.
  • Quote from that page: The driver was trying to fetch more results from the database, but the database did not have a record of the query. This usually means that the cursor timed out on the server side...

MongoDB PHP驱动程序有两个不同的超时时间:

The MongoDB PHP driver has two different timeouts:

  • 连接超时
  • 光标超时

您正在击中游标超时.您可以连接到数据库,但是查询时间已耗尽".

You're hitting a cursor timeout. You can connect to the DB, but your query is "running out of time".

可能的解决方法:

  1. 扩展光标超时.或者,您可以将其设置为零并使它永远存在.
  2. 分批完成此工作.从A获取前1000个_ids,对其进行处理,然后标记为已完成.然后,比上一次运行的结果多获得下一个1000 _ids,依此类推.
  1. Extend the cursor timeout. Or you can set it to zero and make it last forever.
  2. Do this job in batches. Get the first 1000 _ids from A, process them and then mark that you have done so. Then get the next 1000 _ids greater than your last run and so on.

我会建议#2以及处理异常.即使这些不能完全解决问题,它也会帮助您隔离和缓解问题.

I would suggest #2 along with handling the exception. Even if these doesn't completely solve the problem it will help you isolate and mitigate the problem.

这篇关于MongoDB-PHP-MongoCursorException'未找到游标'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆