thinkphp慢查询日志需框架层(database.php配slow_query_time+trigger_sql)与php-fpm层(php-fpm.conf配request_slowlog_timeout+slowlog)双启用,mysql的innodb_print_all_deadlocks仅记录死锁不涉慢查。

ThinkPHP 的慢查询日志不是开个开关就能用的,它分两层:框架层记录(SQL 执行耗时)和 PHP-FPM 层记录(脚本整体卡顿),两者目的不同、配置位置不同、日志内容也完全不重叠。只开一边等于没开。
database.php 里配 slow_query_time 是最直接的框架层慢查开关
这个参数控制 ThinkPHP 自己判断“哪条 SQL 算慢”,单位是毫秒,不是秒。必须配合 'trigger_sql' => true 才生效,否则连 SQL 都不记。
-
slow_query_time设为500表示执行超 500ms 的 SQL 会被标记并写入日志(默认写到runtime/log/下) - 日志里不会自动带请求 URL 或用户 ID,得自己在
think\db\Connection::triggerSqlLog()里补上下文,比如加$request->url()或session_id() - 注意:TP6 已移除该参数,改用中间件或事件监听
DbQuery事件来实现同等逻辑
PHP-FPM 的 request_slowlog_timeout 记的是整个请求卡在哪了
它不关心 SQL,只看 PHP 脚本从收到请求到返回用了多久。哪怕 SQL 只跑 20ms,但中间有个 curl_exec() 卡了 3 秒,它也会被这条日志捕获。
- 配置在
php-fpm.conf里,常见路径如/www/server/php/80/etc/php-fpm.conf(宝塔)或/usr/local/php/etc/php-fpm.conf - 必须同时启用两行:
request_slowlog_timeout = 2s和slowlog = /www/wwwlogs/php_slow.log,缺一不可 - 日志路径目录权限要对,比如
/www/wwwlogs/得属主是www,否则 PHP 进程静默失败,日志文件根本不会生成
MySQL 自身的 innodb_print_all_deadlocks 是查死锁的,不是慢查
很多人混淆这点。这个开关只让 MySQL 把死锁详情输出到错误日志(如 /var/log/mysql/error.log),跟“慢”无关。它不记录耗时,也不触发日志写入逻辑。
- 确认是否生效:执行
SHOW VARIABLES LIKE 'innodb_print_all_deadlocks';,返回ON才算开成功 - 它只对 InnoDB 表有效,MyISAM 表死锁不会记录
- ThinkPHP 日志里看不到这个内容,得去 MySQL 错误日志里 grep “Deadlock found”
最容易被忽略的是日志落盘时机:Swoole 或常驻进程模式下,runtime/log/ 里的日志可能缓存不刷盘,导致你以为没记录;而 PHP-FPM 的 slowlog 是实时 flush 的,更可信。真要定位慢点,得两边日志对照着看——SQL 慢?还是网络/IO/扩展卡住?别只盯 database.php。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











