Laravelで本番DBを使用したらallowed memory size exhausted
状況
laravelで作ったプロジェクトを本番DBを接続したら、以下のエラーが発生。
Allowed memory size of 134217728 bytes exhausted (tried to allocate xxxxxxxx bytes)
試験環境のDBテーブルではレコードがせいぜい数百件しかなかったので何も問題が起きなかったが、本番DBテーブルでは数十万件のレコードがあった。
この状態で多対多リレーションを書き換えようとしたことが原因。
解決
はじめはphpのプロセスメモリ使用制限を設定しているシステム変数memory_limitで設定を変更した。
memory_limit=2M
systemctl restart
しかし、これでもエラーが出続けた。
調べるとlaravelのEloquentにchunk(), chunkByID()、cursor()があり、今回はデータの更新だったのでchunkByID()を利用。
多対多リレーションで使用したテーブルはlettersとstampsだったので、中間DBテーブルをletter_stampで作成。
$count = 0;
DB::table('letter_stamp')->where('active', true)
->chunkById(100, function ($pivots) {
foreach ($pivots as $pivot) use($count) {
$pivot->update(['stamp_id'], null);
$count++;
}
});
中間テーブルのレコードを100件ずつ取得し、値の更新。
その際にクロージャへ親スコープから$count変数を引き継いで、更新件数を把握している。
おまけ
Laravel日本語版公式サイトによるとchunk()では
クロージャから falseを返えせば、それ以上のチャンクの処理を停止できます。
とのことなので、return falseで処理から抜けることができます。
参考資料
Laravel8.x 公式
チャンキングで使用メモリを抑える
LaravelでデータをDBに保存したいときのメモリ不足をなんとかする
Laravel で chunk を使いながらトータル件数を計算
Laravel(Eloquent): chunk() vs cursor()
Author And Source
この問題について(Laravelで本番DBを使用したらallowed memory size exhausted), 我々は、より多くの情報をここで見つけました https://qiita.com/yuzukami1/items/2cdb153ad77e05b5c8ce著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .