ThinkPHP 不归档数据库慢日志,MySQL 慢日志需用 logrotate 配合 flush-logs 归档;TP 慢查询日志由框架记录在 runtime/log/,与 MySQL 慢日志来源、格式、用途均不同。
ThinkPHP 本身不直接归档数据库慢日志,它只负责记录应用层的慢查询(如 SQL 执行超时),而真正的 MySQL 慢查询日志由数据库自身生成、存储和管理。归档动作必须由外部脚本或系统任务完成。
TP5/6 的
是应用层拦截,不是 MySQL 慢日志
TP 配置中的
(单位毫秒)仅控制框架是否在日志中写入“该 SQL 执行耗时超标”的警告,例如:
这类日志写入的是 TP 的运行时日志(如
),和 MySQL 的
完全无关。两者容易混淆,但来源、格式、用途都不同。
TP 慢查询日志:可读性强,带 PHP 调用栈(若开启
),适合快速定位业务代码问题
MySQL 慢日志:原始、带锁时间、扫描行数、客户端 IP 等,是性能分析的黄金数据源
TP 日志默认不自动切割;MySQL 慢日志需手动配置
+
才能落地为文件
MySQL 慢日志文件怎么归档?用
最稳
不要自己写 PHP 脚本去
或
MySQL 慢日志——MySQL 进程会持续写入,直接操作易导致日志丢失或损坏。正确做法是交给
,并配合
。
立即学习
“
PHP免费学习笔记(深入)
”;
示例
:
会关闭当前 slow log 文件并新建一个,确保归档的是“已写完”的完整文件
自动用 gzip 压缩,归档后变成
比手写 PHP 归档脚本更可靠,避免竞态条件和权限问题
TP 应用日志(含慢查询警告)如何切割?靠
配置
TP5.1+ 和 TP6 默认使用
日志驱动,支持按日/大小自动分割,无需额外命令行工具。关键配置项在
中:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
:确保日志名含标准时间戳
(2MB):单文件上限,超限即切新文件
:把 SQL 慢查询单独写入
子目录,方便过滤
:保留最多 30 个日志文件,旧的自动删除(TP6.3+ 支持)
注意:
触发的日志,只有当 SQL 实际执行完毕且超时,才会被记录到
日志里——如果查询卡死在连接阶段或被 kill,TP 层根本捕获不到。
想合并分析 TP 日志 + MySQL 慢日志?加
注释最实用
在 TP 的 DB 查询前注入统一注释,让两条日志能对齐:
这样 MySQL 慢日志里会出现:
再配合 TP 日志里的
行,就能 1:1 关联请求上下文。没有这个标记,跨系统查问题等于盲人摸象。
真正难的不是切割或压缩,而是让日志之间有可追溯的锚点;没锚点的归档,只是把一堆碎片换个地方存着。
slow_query_timeslow_query_time2026-04-11 12:05:23 [ warning ] Slow query: SELECT * FROM users WHERE status = 1 (time: 842ms)runtime/log/xxxx.logslow_query_log_filedebuglog_output=FILEslow_query_loglogrotaterenamegziplogrotatemysqladmin flush-logs/etc/logrotate.d/mysql-slow/var/log/mysql/mysql-slow.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 640 mysql mysql
sharedscripts
postrotate
if [ -f /var/run/mysqld/mysqld.pid ]; then
mysqladmin --defaults-file=/etc/mysql/debian.cnf flush-logs 2>/dev/null || true
fi
endscript
}flush-logscompressmysql-slow.log.1.gzthink\log\driver\FileFileconfig/log.php'time_format' => 'c''file_size' => 2097152'apart_level' => ['error', 'sql']sql'max_files' => 30slow_query_timesql/* APP=xxx */Db::name('users')->where('status', 1)->comment('APP=user_list')->select();# User@Host: php_app[php_app] @ 10.0.1.5 [10.0.1.5]
# Query_time: 1.234567 Lock_time: 0.000123 Rows_sent: 100 Rows_examined: 10000
SET timestamp=1744344323;
/* APP=user_list */ SELECT * FROM users WHERE status = 1;[ sql ] SELECT * FROM users WHERE status = 1