脚本能自动清理MySQL日志吗?

wen 实用脚本 2

本文目录导读:

脚本能自动清理MySQL日志吗?

  1. 清理二进制日志(Binary Logs)
  2. 清理日志表(general_log, slow_log)
  3. 清理数据库中的旧数据(自定义业务表)
  4. 清理错误日志(error log)
  5. 综合清理脚本示例
  6. 安全建议

是的,可以通过脚本自动清理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 "=== 清理完成 ==="

安全建议

  1. 先测试后执行:在测试环境运行脚本,确认不会导致应用异常。
  2. 备份重要日志:部分场景需要保留日志用于审计合规。
  3. 设置监控告警:不依赖脚本手动触发,在监控系统(Zabbix、Prometheus)中设置磁盘使用率告警。
  4. 自动化触发:用 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 分区

脚本确实能自动清理,但关键是先确认哪些日志可以安全删除,再设置合理的保留周期

抱歉,评论功能暂时关闭!