Eloqunetでなぜか Allowed memory size of XXXX bytes exhausted のエラーが出る件
PHPでEloqunetを使用してCSVファイルインポートの処理を作成したところ、数百のインポートでは成功するのに、数千件のインポートを行うと、「Allowed memory size of XXXX bytes exhausted」のエラーが発生してしまいました。
コードを見た感じでは特にメモリを食うような処理は無く、原因が分からずでした。
コードはこんな感じ。(大分端折っているのでこのままでは動きません)
本来なら大量インサートはbulkインサートを使用したいところですが、処理の都合上使用していません。
$handle = fopen($fileData['tmp_name'], 'rb');
$ret = DB::transaction(function() use ($handle) {
$index = 0;
$query = DB::query();
while (($line = fgetcsv($handle)) !== false) {
$query->insert($line);
$index++;
}
return $index;
});
fclose($handle);
// 次のDB操作
HogeHoge::write();
(マークダウンのコード指定に「php」を入れているのですが、色がつかない。。。)
確かに、php.iniのmemory_limitの値は64Mと少なめに設定してるのですが、CSVを丸ごと読み込んでいるわけでもないし、こんな処理でメモリが足りなくなるのはおかしい。。。
トランザクションが怪しいかと思い、外してみたのですが動作は変わらずです。
ログを仕込んでみると、CSV取込自体は無事終了していて、次のDB操作(HogeHoge::write)のタイミングでエラーが発生している。。。
さんざん悩んだ挙句、この処理を呼び出す親クラスを見てみたら、
DB::enableQueryLog(); // サブクラスの処理呼出し $queryLog = DB::getQueryLog(); Log::debug(var_export($queryLog, true));
なんて処理が入っているのをすっかり忘れていました。。。
クエリログが大量に保持されて、エラーが発生しているのでした。
無暗にクエリログを出すと、思わぬところで痛い目に合うというオチです。