MongoDB和PHP库游标超时

时间:2018-08-10 16:04:47

标签: php mongodb mongodb-php

在使用官方MongoDB的PHP库(https://docs.mongodb.com/php-library/master/tutorial/install-php-library/)时,如何将游标超时设置为无限?我读了混合的文档,通常是很难理解是指旧的PHP Driver还是新的(我在说的)。

例如:

$cursor = $col->find();
foreach ($cursor as $document) {
   // slow code..
}

如何防止游标超时(请参见下面的错误)并确保游标随后关闭且没有任何内存泄漏?

Fatal error: Uncaught MongoDB\Driver\Exception\RuntimeException: 
cursor id 123456789 not found in /var/www/html/code.php:1

这里也有一些类似的问题(例如this),但似乎我们缺乏明确的参考。

1 个答案:

答案 0 :(得分:2)

  在/var/www/html/code.php:1中找不到

光标ID 123456789

通常,这是因为应用程序在getMore命令之间花费的时间太长。换句话说,游标在第一次迭代时返回许多记录,并且循环需要很长时间才能请求更多记录。

cursor id not found

游标在服务器上有一个超时,大约10分钟后,如果客户端没有向服务器发送任何命令,它将由于不活动而关闭。在上述情况下,当请求下一批时,光标已被杀死,从而导致错误消息noCursorTimeout:true

有些人试图通过在游标上设置getMore来禁用游标超时。尽管不建议这样做,因为当noCursorTimeout从服务器返回的结果存在问题时,您可能会得到一个永久存在的游标(僵尸)。也就是说,在客户端断开连接后,带有session的游标可能仍在服务器上保持活动状态。

有两种可能的解决方案:

  • 减少cursor.batchSize()。这是因为减少每批记录的数量会减少游标不活动。即以前处理15分钟的100条记录,现在只有7.5分钟的50条记录。

  • 手动创建会话,即PHPLIB MongoDB\Client::startSession()。然后将其作为session选项传递给查询。在长时间运行的迭代过程中,应定期使用相同的会话(即ping服务器)执行其他一些数据库交互。这将使noCursorTimeout保持活动状态(30分钟超时);但是,它不会使光标保持活动状态,因此可以将其与{{1}}结合使用。

相关问题