mysql安装后配置日志轮转与清理策略

来源:这里教程网 时间:2026-02-28 20:51:14 作者:

MySQL 的错误日志和慢查询日志默认不轮转

MySQL 安装后,

error.log
slow_query_log_file
默认是持续追加写入的,不会自动切割或删除。长期运行下可能占满磁盘,尤其在开启慢查询日志且业务 SQL 较多时。
mysqld
本身不提供内置轮转机制(不像 PostgreSQL 的
log_rotation_age
),必须靠外部工具配合配置。

用 logrotate 管理 MySQL 日志最稳妥

Linux 发行版普遍自带

logrotate
,它是管理日志轮转的事实标准。关键点在于:必须让 MySQL 重新加载日志文件句柄,否则轮转后新日志仍写入旧文件(因为 mysqld 进程还持有原文件 fd)。

确保 MySQL 配置中显式指定了日志路径,例如:
log_error = /var/log/mysql/error.log
slow_query_log_file = /var/log/mysql/mysql-slow.log
/etc/logrotate.d/mysql
中写入如下配置(路径和用户需按实际调整):
/var/log/mysql/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 640 mysql mysql
    sharedscripts
    postrotate
        if [ -f /var/run/mysqld/mysqld.pid ]; then
            kill -USR1 `cat /var/run/mysqld/mysqld.pid`
        fi
    endscript
}

postrotate
中的
kill -USR1
是关键:它通知 mysqld 关闭当前日志文件并重新打开(即 reopen log file),否则轮转无效。注意不是
SIGHUP
—— MySQL 对
SIGHUP
的行为是重载配置,不一定刷新日志;
USR1
才是官方文档明确用于日志 reopen 的信号。

binlog 轮转和清理要单独处理

binlog
不走
logrotate
,因为它是 MySQL 自己按大小或时间生成的,且依赖于复制和恢复一致性。清理必须通过 MySQL 内部命令或参数控制,否则直接删文件会导致主从断裂或
mysql-bin.index
不一致。

设置自动过期:在
my.cnf
中添加
expire_logs_days = 7
(MySQL 5.7 及以前)或
binlog_expire_logs_seconds = 604800
(MySQL 8.0+)
手动清理(谨慎):
PURGE BINARY LOGS BEFORE '2024-06-01 00:00:00';
PURGE BINARY LOGS TO 'mysql-bin.000123';
确认当前状态:
SHOW BINARY LOGS;
SHOW MASTER STATUS;

如果启用了 GTID,

PURGE
仍安全,但不能低于
gtid_purged
的最小事务;可通过
SELECT @@global.gtid_purged;
查看。

避免踩坑的三个硬性检查点

很多线上事故源于轮转配置看似生效,实则未触发 reopen 或权限错乱:

logrotate
配置后,手动执行
logrotate -d /etc/logrotate.d/mysql
(调试模式)确认无报错,再用
-f
强制跑一次观察文件变化
检查
mysqld
启动用户是否真能向日志目录写入:比如
/var/log/mysql
目录属主是
mysql:mysql
,权限为
750
,且
create 640 mysql mysql
中的用户组名与实际一致
确认
mysqld
进程 PID 文件路径和读取权限:若
/var/run/mysqld/mysqld.pid
不存在或不可读,
postrotate
里的
kill -USR1
会失败,日志继续写进已轮转的旧文件

真正起效的日志清理,从来不是配完就完事——必须验证 reopen 是否成功,以及磁盘空间是否真实释放。

相关推荐