/var/log/php-fpm-slow.log ≠ MySQL 慢查询日志,二者记录完全不同的慢操作,但常被混淆。理解其区别,才能精准定位性能瓶颈。


一、日志机制:谁在记录?记录什么?

日志 生成者 记录内容 本质
php-fpm-slow.log PHP-FPM PHP 脚本执行慢
(从请求开始到结束)
应用层慢
MySQL 慢查询日志 MySQL Server SQL 语句执行慢
(单条 SQL 超过阈值)
数据库层慢

🔑 核心区别

  • FPM 慢日志:整个 PHP 脚本耗时(含 I/O、计算、DB 查询等);
  • MySQL 慢日志:单条 SQL 语句耗时。

二、触发条件:何时写入日志?

1. php-fpm-slow.log
  • 配置/etc/php/8.2/fpm/pool.d/www.conf):
    slowlog = /var/log/php-fpm-slow.log
    request_slowlog_timeout = 5s  ; 脚本总执行时间 > 5 秒
    
  • 触发
    • 整个 PHP 请求(从 index.php 开始到 exit);
    • 包含:文件读写、网络请求、所有 MySQL 查询、计算等。
2. MySQL 慢查询日志
  • 配置my.cnf):
    slow_query_log = 1
    slow_query_log_file = /var/log/mysql-slow.log
    long_query_time = 2          ; 单条 SQL > 2 秒
    
  • 触发
    • 单条 SQL 语句(如 SELECT * FROM users);
    • 不含:PHP 代码、文件 I/O、网络延迟。

⚠️ 关键

  • FPM 慢日志可能包含 MySQL 慢查询,但不止于此
  • MySQL 慢日志只关心 SQL,不关心 PHP

三、日志内容结构对比

php-fpm-slow.log 示例:
[15-Jun-2025 10:00:00]  [pool www] pid 12345
script_filename = /var/www/html/index.php
[0x00007f1234567890] sleep() /var/www/html/index.php:10
[0x00007f1234567891] PDO->query() /var/www/html/index.php:15
  • 关键信息
    • 完整调用栈(含文件+行号);
    • 所有慢操作sleep()PDO->query() 等)。
MySQL 慢查询日志示例:
# Time: 2025-06-15T10:00:01.123456Z
# User@Host: root[root] @ localhost []
# Query_time: 3.21  Lock_time: 0.01  Rows_sent: 1000  Rows_examined: 100000
SET timestamp=1718452801;
SELECT * FROM users WHERE email LIKE '%gmail%';
  • 关键信息
    • 单条 SQL
    • 执行时间、扫描行数、返回行数

💡 关联点

  • 若 FPM 日志显示 PDO->query() 慢,
  • 则需查 MySQL 慢日志,确认是否 SQL 问题。

四、协同诊断:如何联合分析?

场景:API 偶发慢(>5 秒)
  1. 查 FPM 慢日志
    • 发现 index.php:15PDO->query() 耗时 4.8 秒;
  2. 查 MySQL 慢日志
    • 发现同时间点 SELECT * FROM users ... 耗时 4.7 秒;
  3. 根因无索引导致全表扫描
  4. 修复
    • email 字段添加索引;
    • 优化查询(避免 LIKE '%...%')。
场景:FPM 慢,但 MySQL 不慢
  • FPM 日志sleep(10) 耗时 10 秒;
  • MySQL 日志:无慢查询;
  • 根因PHP 代码逻辑问题(如死循环、外部 API 无超时);
  • 修复
    • 为外部调用加超时;
    • 移除 sleep()

五、高危误区

🚫 误区 1:“FPM 慢 = MySQL 慢”
  • 真相
    • FPM 慢可能因磁盘 I/O(日志写入)、网络(API 调用)、计算(大数组处理);
    • 必须看调用栈
🚫 误区 2:“MySQL 不慢,FPM 就不该慢”
  • 真相
    • 100 次快查询(10ms each) = 1 秒,可能触发 FPM 慢日志;
    • N+1 问题:无单条慢 SQL,但总耗时高。
🚫 误区 3:“只开一个慢日志就够了”
  • 真相
    • FPM 慢日志 + MySQL 慢日志 + EXPLAIN 三位一体,缺一不可。

六、最佳实践:配置建议

1. FPM 慢日志
; /etc/php/8.2/fpm/pool.d/www.conf
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 2  ; 生产建议 1–2 秒
2. MySQL 慢日志
# /etc/mysql/my.cnf
slow_query_log = 1
slow_query_log_file = /var/log/mysql-slow.log
long_query_time = 1          ; 生产建议 0.5–1 秒
log_queries_not_using_indexes = 1  ; 记录无索引查询
3. Laravel 辅助
// 记录 DB 查询到日志(含时间)
DB::listen(function ($query) {
    if ($query->time > 100) { // 100ms
        \Log::warning('Slow query', [
            'sql' => $query->sql,
            'time' => $query->time,
            'bindings' => $query->bindings,
        ]);
    }
});

七、总结

问题 答案
FPM 慢日志 = MySQL 慢日志 ❌ 完全不同
FPM 慢一定因 MySQL 慢 ❌ 可能因 I/O/网络/代码
如何精准定位 FPM 日志看调用栈 → MySQL 日志看 SQL → EXPLAIN 优化

核心心法
FPM 慢日志是“症状”,
MySQL 慢日志是“可能病因之一”

当你能:

  • 用 FPM 日志定位慢操作行号;
  • 用 MySQL 日志确认是否 SQL 问题;

你就掌握了PHP 应用性能诊断的黄金组合

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐