Laravel 5.7占用MySQL数据库100% CPU且队列无可见任务求助
MySQL长期高CPU占用排查与解决思路(Laravel环境)
问题现象
- MySQL CPU持续维持95%以上,即便应用无明显用户活动也不下降,仅在应用运行一段时间后触发该问题
- 活跃数据库连接数从数十个逐步攀升至数百个
- RDS实例上存在十几个MySQL进程,每个进程占用约8%的CPU资源
- 已通过
php artisan queue:listen排查Laravel队列,未发现待执行任务 - 数据库查询日志显示存在大量循环执行的通用查询,但无法直接定位来源
- 应用日志、错误日志未发现明显异常
一、定位高CPU进程的核心SQL
- 执行
SHOW PROCESSLIST;或通过RDS控制台查看进程列表,重点提取那十几个高CPU进程的完整SQL语句,记录执行频率 - 对高频执行的SQL运行
EXPLAIN分析执行计划,检查是否存在全表扫描、未使用索引、临时表创建等资源消耗点 - 开启MySQL慢查询日志(设置
long_query_time=1),捕获耗时查询,结合pt-query-digest统计查询的资源占比和执行频次 - 观察进程的
Time字段,区分是长期运行的阻塞进程,还是短时间内重复创建的高频执行进程
二、排查Laravel应用端的隐式循环逻辑
- 检查模型观察者:确认模型的
saved/updated/deleted等观察者方法中,是否存在触发数据库更新的逻辑,避免出现“更新模型→触发观察者→再次更新模型”的循环 - 排查事件监听:检查Laravel事件与监听器的绑定,确认监听器中是否有递归调用或循环查询数据库的逻辑
- 核对定时任务:用
crontab -l查看系统定时任务,执行php artisan schedule:list查看Laravel定时任务,排查是否有任务在后台循环执行且未正常退出 - 检查第三方扩展:排查缓存、统计、日志类第三方包,确认是否存在后台自动循环查询数据库的逻辑
- 验证持久连接配置:查看
config/database.php中是否开启了persistent连接,若连接未正确释放,会导致连接数攀升并持续占用CPU资源
三、数据库层面的配置与优化
- 优化索引:针对高频通用查询,根据
EXPLAIN结果添加合适的索引,避免全表扫描消耗CPU - 检查InnoDB状态:执行
SHOW ENGINE INNODB STATUS;,排查是否存在未提交的事务、锁等待等情况,这类问题会持续占用数据库资源 - 调整连接参数:确认MySQL的
max_connections配置合理,若使用连接池,检查Laravel的数据库连接池配置是否存在连接泄漏 - 优化RDS参数:关闭不必要的
query_cache_type(高并发场景下会增加CPU开销),调整sort_buffer_size、join_buffer_size等参数,避免资源过度分配
四、代码层面的深度定位
- 开启Laravel查询日志:在
config/database.php中开启log选项,或在可疑代码块中临时调用DB::enableQueryLog(),结合DB::getQueryLog()定位触发高频查询的代码位置 - 排查递归逻辑:检查业务代码中的递归调用,确认是否存在未设置终止条件的情况,导致循环查询数据库
- 检查队列异常任务:执行
php artisan queue:failed查看失败任务列表,用php artisan queue:monitor监控队列状态,排查是否存在失败任务重复执行的情况
内容的提问来源于stack exchange,提问作者Level Up Development
相关产品推荐
相关产品推荐

