一、先理解 binlog 的作用
binlog 是 MySQL 的二进制日志,核心用途:
数据恢复:通过 binlog 恢复误删 / 误改的数据(比如执行DROP TABLE后,可通过 binlog 回滚)。
主从复制:主库的 binlog 同步到从库,保证主从数据一致。
审计:记录所有写操作(INSERT/UPDATE/DELETE/DDL),可追溯操作历史。
直接删除 binlog 可能导致:
无法通过 binlog 恢复数据(若后续需要恢复)。
主从架构中,从库未同步完 binlog 时,主库删除对应文件会导致从库复制中断(报错Got fatal error 1236)。
二、安全清理 binlog 的 3 种方法(按推荐优先级排序)
方法 1:通过purge binary logs命令手动清理(最安全)
适用于临时清理,可精确控制删除范围,MySQL 会自动检查 binlog 的依赖(如从库是否已同步),避免误删。
常用命令(直接执行,无需停库):
1. 先登录MySQL(root或有SUPER权限的用户)
powershell
mysql -u root -p
2. 查看当前正在使用的binlog文件(最后一个文件不能删!)
powershell
show master status;

说明:当前使用的是 binlog.001254,删除时必须排除它!
3. 清理指定文件之前的所有binlog(推荐,精确可控)
例:删除 binlog.001254 之前的所有binlog(不包含binlog.001254)
powershell
purge binary logs to 'binlog.001254';
4. 按时间清理(删除3天前的所有binlog)
powershell
purge binary logs before date_sub(now(), interval 3 day);
5. 验证清理结果(查看剩余的binlog文件)
powershell
show binary logs;
关键注意:
若存在主从复制,执行purge前需确认从库已同步完要删除的 binlog(避免从库缺失日志):
powershell
-- 在主库执行,查看所有从库的同步状态(需主库开启了从库监控)
show slave hosts;
-- 或登录从库执行,查看从库当前同步的binlog文件和位置
show slave status\G;
-- 重点看:Master_Log_File(从库当前同步的主库binlog文件)、Read_Master_Log_Pos(同步位置)
-- 确保主库要删除的binlog文件,均早于从库的 Master_Log_File,且从库已同步完成(Read_Master_Log_Pos 等于主库对应文件的 Position)
方法 2:配置 binlog 自动过期(长期最优方案)
无需手动清理,让 MySQL 自动删除过期的 binlog,适合生产环境长期使用。
配置步骤:
1.编辑 MySQL 配置文件(my.cnf 或 my.ini,位置通常在 /etc/my.cnf、/etc/mysql/my.cnf 或 /usr/local/mysql/etc/my.cnf):
powershell
vi /etc/my.cnf
2.在 [mysqld] 节点下添加以下配置:
powershell
# 设置binlog自动过期时间为7天(可根据需求调整,如3天、15天)
expire_logs_days = 7
# (可选)限制单个binlog文件大小(默认1G,避免文件过大)
max_binlog_size = 1G
3.重启 MySQL 使配置生效:
powershell
# CentOS/RHEL
systemctl restart mysqld
# 或
service mysqld restart
# Ubuntu/Debian
systemctl restart mysql
4.验证配置是否生效:
powershell
-- 登录MySQL执行
show variables like 'expire_logs_days';
-- 输出示例:+------------------+-------+
-- | Variable_name | Value |
-- +------------------+-------+
-- | expire_logs_days | 7 |
-- +------------------+-------+
说明:配置后,MySQL 会在每次启动、日志轮转时,自动删除超过 expire_logs_days 天数的 binlog 文件。
方法 3:紧急清理(仅当磁盘满到无法操作时使用)
若磁盘已 100% 占用,无法登录 MySQL 执行purge,可临时手动删除,但需严格按以下步骤操作(风险较高):
1.先停止 MySQL 服务(避免删除正在写入的 binlog 文件):
powershell
systemctl stop mysqld
2.进入 binlog 目录(通常在 /var/lib/mysql/,可通过show variables like 'datadir'; 查看):
powershell
cd /var/lib/mysql/
3.手动删除除当前正在使用的 binlog 文件外的所有过期文件:
powershell
# 先查看当前使用的binlog文件(停止服务前可通过show master status查看,或看文件修改时间,最新的通常是正在使用的)
ls -lt mysql-bin.* | head -10 # 按修改时间排序,最后一个是当前使用的
# 例:当前使用的是 mysql-bin.000123,删除之前的所有文件
rm -rf mysql-bin.000001 mysql-bin.000002 ... mysql-bin.000122
4.重启 MySQL 服务:
powershell
systemctl start mysqld
5.登录 MySQL 验证 binlog 状态:
powershell
show binary logs; # 确认剩余的binlog文件正常
show master status; # 确认当前binlog文件正确
风险提示:此方法可能导致数据恢复失败或主从复制中断,仅在紧急情况下使用,事后需立即配置expire_logs_days自动过期。
三、常见问题
1.如何查看 binlog 文件占用的存储空间?
powershell
# 进入binlog目录
cd /var/lib/mysql/
# 查看单个binlog文件大小
ls -lh mysql-bin.*
# 查看所有binlog文件总大小
du -sh mysql-bin.*
2.是否可以禁用 binlog?
若无需数据恢复、主从复制,可禁用 binlog(节省磁盘空间):
powershell
编辑 my.cnf,在[mysqld]节点下添加:skip-log-bin
重启 MySQL:systemctl restart mysqld
注意:生产环境不建议禁用,除非确认不需要数据恢复(如测试环境)。
3.清理后磁盘空间未释放?
原因:MySQL 可能仍在占用已删除的 binlog 文件句柄(即使文件已删除,进程未释放则空间不释放)。
解决:重启 MySQL 服务(systemctl restart mysqld),或执行flush logs;(刷新日志,触发文件句柄释放)。
总结
- 生产环境优先使用 方法 2(配置自动过期),一劳永逸。
- 临时清理优先使用 方法 1(purge 命令),安全无风险。
- 仅紧急情况(磁盘满)使用 方法 3(手动删除),事后需补全自动过期配置。
- 核心原则:不删当前正在使用的binlog,主从架构下先确认从库同步状态再清理。