mysql事务日志(binlog)需单独备份,不能用mysqldump替代;必须通过flush logs后拷贝或mysqlbinlog解析,配合expire_logs_days等配置自动管理,并与全量备份严格对齐以实现时间点恢复。

MySQL 事务日志(binlog)不能直接用 mysqldump 备份
mysqldump 只导出数据和结构,完全不触碰 binlog。事务日志是 MySQL 的二进制日志,记录所有 DDL/DML 的逻辑操作,用于主从复制和时间点恢复——它必须单独备份,且只能通过文件拷贝或 mysqlbinlog 工具读取。
常见误操作:把 mysqldump 当成全量备份方案,结果发现无法恢复到某个具体时间点,因为缺失 binlog。
-
binlog文件本身是二进制格式,不能直接编辑或用文本工具打开(除非用mysqlbinlog解析) - 启用
binlog前必须设置server-id,否则 MySQL 启动时可能拒绝加载 -
binlog_format推荐用ROW,避免STATEMENT在某些函数(如NOW()、UUID())下主从不一致
如何安全拷贝正在写入的 binlog 文件
直接 cp 正在使用的 binlog 文件(如 mysql-bin.000012)极可能导致损坏,因为文件末尾可能未刷盘或处于写入中。正确做法是先执行 FLUSH LOGS,让 MySQL 关闭当前文件并新建一个:
mysql -u root -p -e "FLUSH LOGS;"
之后再拷贝上一个已关闭的文件(例如刚被轮换下来的 mysql-bin.000011),确保内容完整。
- 用
SHOW BINARY LOGS;查看当前活跃的binlog列表及文件大小 - 用
SHOW MASTER STATUS;查看当前正在写的文件名和 position,避免误删或漏备 - 生产环境建议配合
rsync --remove-source-files或硬链接方式做原子拷贝,减少窗口期
用 mysqlbinlog 提取指定时间/位置范围的 SQL
还原时通常不需要整个 binlog 文件,而是提取某段时间或某个 position 起始的操作。核心工具是 mysqlbinlog,它能将二进制日志转为可读 SQL:
mysqlbinlog --start-datetime="2024-06-15 10:30:00" --stop-datetime="2024-06-15 10:45:00" /var/lib/mysql/mysql-bin.000011 > restore.sql
注意:时间精度取决于日志写入时刻,不是执行时刻;更精确的方式是用 --start-position 和 --stop-position,需先用 mysqlbinlog -v 查看事件 offset。
-
--base64-output=DECODE-ROWS -v用于查看ROW格式日志的具体行变更(含旧值/新值) - 若日志启用了加密(
binlog_encryption=ON),必须用对应密钥启动mysqlbinlog,否则报错Failed to open file: ... unknown encryption type - 跨服务器恢复时,注意
server-id冲突问题,可在导入前加SET SESSION sql_log_bin = 0;
自动轮转 + 定期清理 binlog 的关键配置
放任 binlog 无限制增长会撑爆磁盘,但删早了又影响恢复能力。靠人工管理不可靠,应通过 MySQL 自身机制控制生命周期:
在 my.cnf 中设置:
expire_logs_days = 7 max_binlog_size = 100M
前者表示自动删除 7 天前的日志,后者控制单个文件最大体积(达到后自动轮转)。注意:expire_logs_days 在 MySQL 8.0.11+ 已被 binlog_expire_logs_seconds 替代,设为 604800 效果相同。
- 修改后需重启或执行
SET GLOBAL binlog_expire_logs_seconds = 604800;生效 - 手动清理用
PURGE BINARY LOGS BEFORE '2024-06-10 00:00:00';,比直接rm安全,MySQL 会同步更新索引文件mysql-bin.index - 监控可用空间时,别只看
df,还要查SHOW BINARY LOGS;总大小,防止小文件堆积
binlog 备份不是孤立动作——它必须和最近一次物理备份(如 xtrabackup)或逻辑备份(mysqldump)严格对齐,且 position 或 datetime 必须能衔接上。漏掉任意一环,时间点恢复就失效。










