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 必须能衔接上。漏掉任意一环,时间点恢复就失效。
