跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

ThinkPHP如何做数据库慢日志归档_ThinkPHP日志切割策略详解【详解】

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

相关文章