mongodb には ->remove()->limit() はありません。そのため、タスクを解決するために小さなスクリプトを使用します。
<?php
$conn = new Mongo('127.0.0.1');
$db = $conn->experimentDB;
$experimentCollection = $db->experimentCollection;
foreach($ruleset AS $ruleset_item)
{
$max_remove_loops=3;
$max_limit_per_loop=1000;
MongoCursor::$timeout = 1*60*1000;
for($remove_loops=0;$remove_loops<$max_remove_loops;$remove_loops++)
{
if(!TEST)
$cursor = $experimentCollection->find($ruleset_item)->limit($max_limit_per_loop);//->skip($remove_loops*$max_limit_per_loop);
else
$cursor = $experimentCollection->find($ruleset_item)->limit($max_limit_per_loop)->skip($remove_loops*$max_limit_per_loop);
$items=0;
foreach($cursor AS $cursor_item)
{
//print_r($cursor_item['_id']);
print('.');
if(!TEST)
$experimentCollection->remove(array('_id' => $cursor_item['_id']));
$items++;
}
if($items==0)
{
break;
print(' that was the last one. DONE ');
}
//$cursor->reset();
}
}
?>
これはで終わった
致命的なエラー:メッセージ「カーソルがタイムアウトしました (タイムアウト: 60000、残り時間: 0:0、ステータス: 0)」を含む例外「MongoCursorTimeoutException」がキャッチされませんでした
そのため、max_remove_loops と max_limit_per_loop でタスクを分割しようとし、max_limit_per_loop を 1min、1h、2h などに変更しました。
ただし、数百回の削除後にスクリプトがハングする別の問題があるようです。200 ~ 2000 の間の場合もあります。(print('.')でカウントされます)
これはランダムなバグのように見え、mongodb が管理しなければならない他のタスク、RAM、CPU 負荷に依存しています。
推測ですが、ループが削除のためにキューに入れられたのと同じカーソルをわずかな遅延でキャッチしている場合、削除のために問題が発生している可能性がありますか?
このスクリプトをフォールト トレラントに修正し、ハングする代わりに続行するにはどうすればよいですか?