6.4.8 日志轮转、归档与磁盘容量规划
日志轮转与归档的目标是控制磁盘占用、保障恢复链路连续性并满足合规留存。MySQL日志主要包括 error、slow、general、binlog、relay、undo/redo(引擎维护)等,其中重点规划 error/slow/general/binlog/relay。建议明确:哪类日志用于排障、哪类用于审计、哪类用于恢复,并为不同环境(生产/测试)设定不同留存与清理策略。
原理草图(轮转—归档—清理闭环):
一、关键配置与命令示例
1)binlog 过期与一致性设置(my.cnf)
[mysqld]
# binlog 过期策略(8.0 推荐秒级)
binlog_expire_logs_seconds = 604800 # 7天
binlog_format = ROW
sync_binlog = 1
# 日志落盘目录(建议独立磁盘)
log_bin = /data/mysql/binlog/mysql-bin
2)error/slow/general 日志开启与路径
[mysqld]
log_error = /data/mysql/log/error.log
slow_query_log = ON
slow_query_log_file = /data/mysql/log/slow.log
long_query_time = 2
general_log = OFF
general_log_file = /data/mysql/log/general.log
3)手动轮转与切换新文件
# 切换到新日志文件(error/slow/general/binlog)
mysqladmin -uroot -p flush-logs
# 或在 MySQL 客户端执行
mysql -uroot -p -e "FLUSH LOGS;"
4)logrotate 示例(/etc/logrotate.d/mysql)
/data/mysql/log/*.log {
daily
rotate 14
missingok
compress
delaycompress
notifempty
create 640 mysql mysql
sharedscripts
postrotate
/usr/bin/mysqladmin -uroot -p'YourPass' flush-logs >/dev/null 2>&1
endscript
}
预期效果:每日轮转,保留14份,压缩归档,轮转后新日志文件自动生成。
5)relay log 自动清理与控制
[mysqld]
relay_log = /data/mysql/relaylog/relay-bin
relay_log_purge = ON
二、归档流程与脚本示例
建议与备份链路绑定:全量备份完成后,将对应时间点之前的 binlog 归档到低成本存储并生成索引清单。
归档脚本示例(/usr/local/bin/archive_binlog.sh):
#!/usr/bin/env bash
set -euo pipefail
BINLOG_DIR="/data/mysql/binlog"
ARCHIVE_DIR="/data/archive/binlog"
INDEX_FILE="${ARCHIVE_DIR}/index.txt"
mkdir -p "${ARCHIVE_DIR}"
# 列出已写完的 binlog(排除当前正在写入)
LAST_BINLOG=$(mysql -uroot -p'YourPass' -e "SHOW MASTER STATUS\G" | awk '/File:/ {print $2}')
for f in ${BINLOG_DIR}/mysql-bin.*; do
base=$(basename "$f")
if [[ "$base" < "$LAST_BINLOG" ]]; then
gzip -c "$f" > "${ARCHIVE_DIR}/${base}.gz"
sha256sum "${ARCHIVE_DIR}/${base}.gz" >> "${ARCHIVE_DIR}/checksum.sha256"
echo "${base}.gz" >> "${INDEX_FILE}"
# 归档成功后删除本地旧文件
rm -f "$f"
fi
done
echo "Archive done at $(date)" >> "${ARCHIVE_DIR}/archive.log"
说明:以当前 binlog 文件为界,归档之前的文件;生成校验与索引,便于审计与恢复追踪。
三、磁盘容量规划与计算
估算公式:
日均日志量 ≈ 写入峰值(MB/s)× 86400 × 平均写入比例
保留空间 ≈ 日均日志量 × 保留天数 × 安全系数(1.3~1.5)
示例:峰值 20MB/s,平均 30%,保留 7 天
日均日志量 ≈ 20 × 86400 × 0.3 ≈ 518400MB ≈ 506GB
保留空间 ≈ 506GB × 7 × 1.3 ≈ 4.6TB
建议:binlog 独立磁盘/分区,至少预留数据盘 20%~30%。
四、排错与应急处理
1)日志暴涨导致磁盘告警
# 查看最近1小时日志增长
du -h --max-depth=1 /data/mysql/log /data/mysql/binlog
# 立即关闭 general/slow(非必要时)
mysql -uroot -p -e "SET GLOBAL general_log=OFF; SET GLOBAL slow_query_log=OFF;"
2)误删 relay log 导致复制中断
-- 检查复制状态
SHOW SLAVE STATUS\G
-- 重新拉取 relay log(需谨慎)
STOP SLAVE;
RESET SLAVE ALL; -- 可能需要重新配置主从
CHANGE MASTER TO MASTER_HOST='master', MASTER_LOG_FILE='mysql-bin.000123', MASTER_LOG_POS=456;
START SLAVE;
3)binlog 未过期积压
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';
SHOW BINARY LOGS;
-- 手工清理(确保备份完整)
PURGE BINARY LOGS BEFORE '2024-07-01 00:00:00';
五、练习与检查清单
1)练习:配置 logrotate 并验证轮转
- 写入慢查询后触发轮转
- 检查新文件生成:ls -l /data/mysql/log/
- 确认旧文件压缩:ls -l /data/mysql/log/*.gz
2)练习:模拟归档并校验
bash /usr/local/bin/archive_binlog.sh
tail -n 5 /data/archive/binlog/index.txt
sha256sum -c /data/archive/binlog/checksum.sha256 | tail -n 5
3)检查清单
- [ ] binlog 过期策略与备份点一致
- [ ] 轮转后自动切换新日志文件
- [ ] 归档目录含索引与校验
- [ ] 磁盘水位 80/90% 告警设置
- [ ] 恢复抽检(至少月度)