You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel v8.52.0使用Eloquent Model save()做数据库迁移时内存溢出排查

Laravel 8.52.0 Eloquent批量操作内存溢出问题解决方案

问题场景

在Laravel v8.52.0版本下使用Eloquent Model执行批量数据库迁移操作时,出现内存持续上涨最终溢出的错误,测试代码如下:

public function handle()
{
  for ($i = 0; $i < 100; $i++) {
    Customer::chunkById(1000, function ($customers) use ($i) {
      $this->print_progress();
      foreach ($customers as $customer) {
        $customer->first_name = (string)$i;
        $customer->save();
      }
    });
  }
}

错误日志

运行时内存线性攀升,最终触发PHP内存上限报错,日志内容如下:

usage:    27MB - peek:    27MB
usage:    33MB - peek:    33MB
usage:    39MB - peek:    39MB
...
...
usage:   491MB - peek:   491MB
usage:   496MB - peek:   496MB
PHP Fatal error:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 20480 bytes) in /home/vagrant/code/billing/vendor/laravel/framework/src/Illuminate/Support/Str.php on line 855
PHP Fatal error:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 32768 bytes) in /home/vagrant/code/billing/vendor/symfony/error-handler/Error/FatalError.php on line 1

根因定位

内存泄漏由Laravel官方的Telescope调试组件导致,该组件默认会记录所有数据库查询、模型操作等运行日志,且在命令行执行长耗时批量任务时不会自动释放已记录的日志内存,随着操作量增加内存占用持续上涨,最终触发溢出。

修复方案

  • 全局临时关闭Telescope:执行批量任务前在.env配置文件中修改参数TELESCOPE_ENABLED=false,任务执行完成后再按需开启即可完全解决该场景下的内存泄漏问题。
  • 单任务禁用Telescope记录:如果不需要全局关闭Telescope,可在任务代码开头添加如下代码,仅对当前批量任务禁用日志记录:
\Laravel\Telescope\Telescope::stopRecording();
  • 可选性能优化:现有逐行调用save()的逻辑数据库IO开销较高,可调整为批量更新逻辑进一步降低任务耗时和资源占用,示例如下:
public function handle()
{
  for ($i = 0; $i < 100; $i++) {
    Customer::where('id', '>', $i * 10000)
      ->where('id', '<=', ($i + 1) * 10000)
      ->update(['first_name' => (string)$i]);
    $this->print_progress();
  }
}

内容的提问来源于stack exchange,提问作者Shengtian Liao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 19:45:01