本文目录导读:

是的,可以通过脚本自动清理MySQL日志,下面是几种常见的清理方式和示例脚本,使用前请务必谨慎操作。
清理二进制日志(Binary Logs)
MySQL的二进制日志(binlog)用于主从复制和PITR(时间点恢复),最容易占用空间。
使用 PURGE BINARY LOGS 命令(推荐)
#!/bin/bash # mysql_clean_binlog.sh # 数据库连接信息 MYSQL_USER="root" MYSQL_PASSWORD="your_password" MYSQL_HOST="localhost" # 保留最近3天的二进制日志 DAYS=3 # 执行清理 mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -e " PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL $DAYS DAY); "
设置自动过期(更推荐)
-- 在 MySQL 中执行(或写进脚本) SET GLOBAL binlog_expire_logs_seconds = 259200; -- 3天 = 3*24*3600
在配置文件 my.cnf 中永久设置:
[mysqld] expire_logs_days = 3 # 适用于 MySQL 8.0 之前 binlog_expire_logs_seconds = 259200 # 适用于 MySQL 8.0+
清理日志表(general_log, slow_log)
如果是将日志记录到 mysql 数据库中的表:
#!/bin/bash # mysql_clean_log_tables.sh MYSQL_USER="root" MYSQL_PASSWORD="your_password" mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -e " TRUNCATE TABLE mysql.general_log; TRUNCATE TABLE mysql.slow_log; "
⚠️ 前提:需先关闭日志记录或使用
SET GLOBAL general_log = OFF;,否则 TRUNCATE 会失败。
清理数据库中的旧数据(自定义业务表)
如果你的业务表积累了大量无用日志数据:
#!/bin/bash # mysql_clean_old_data.sh MYSQL_USER="root" MYSQL_PASSWORD="your_password" DATABASE="my_db" TABLE="my_log_table" # 删除7天前的数据 DAYS=7 mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -D "$DATABASE" -e " DELETE FROM $TABLE WHERE created_at < DATE_SUB(NOW(), INTERVAL $DAYS DAY); "
对于大表,建议分批删除以避免锁表(使用
LIMIT循环)。
清理错误日志(error log)
MySQL错误日志是文本文件,MySQL不提供自动清理命令,需操作系统层面处理:
#!/bin/bash
# mysql_clean_error_log.sh
ERROR_LOG="/var/log/mysql/error.log"
MAX_SIZE_MB=500
# 如果文件大小超过500MB,清空(备份前)
if [ $(stat -c%s "$ERROR_LOG") -gt $((MAX_SIZE_MB * 1024 * 1024)) ]; then
# 备份
cp "$ERROR_LOG" "${ERROR_LOG}.$(date +%Y%m%d)"
# 清空
> "$ERROR_LOG"
# 重启日志(或发送 USR1 信号让 MySQL 重新打开日志文件)
mysqladmin -u root -p"$your_password" flush-logs
fi
综合清理脚本示例
#!/bin/bash # mysql_full_clean.sh MYSQL_USER="root" MYSQL_PASSWORD="your_password" MYSQL_HOST="localhost" echo "=== 开始清理MySQL日志 ===" # 1. 清理7天前的二进制日志 echo "清理二进制日志..." mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -e " PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY); " # 2. 清理业务日志表(7天前) echo "清理业务日志表..." mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -D "my_database" -e " DELETE FROM operation_log WHERE create_time < DATE_SUB(NOW(), INTERVAL 7 DAY); " # 3. 清空并回收表空间(InnoDB) echo "回收表空间..." mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -D "my_database" -e " OPTIMIZE TABLE operation_log; " echo "=== 清理完成 ==="
安全建议
- 先测试后执行:在测试环境运行脚本,确认不会导致应用异常。
- 备份重要日志:部分场景需要保留日志用于审计合规。
- 设置监控告警:不依赖脚本手动触发,在监控系统(Zabbix、Prometheus)中设置磁盘使用率告警。
- 自动化触发:用
crontab定时执行:# 每天凌晨2点执行 0 2 * * * /path/to/mysql_clean_binlog.sh
| 日志类型 | 清理方法 | 建议方式 |
|---|---|---|
| 二进制日志 | PURGE BINARY LOGS |
设置自动过期 (binlog_expire_logs_seconds) |
| 错误日志 | 操作系统层面截断 | cron + flush-logs |
| 慢查询/通用日志 | TRUNCATE TABLE |
记录到文件而非表 |
| 业务日志表 | DELETE ... WHERE |
分区表 + 定期 drop 分区 |
脚本确实能自动清理,但关键是先确认哪些日志可以安全删除,再设置合理的保留周期。