必须执行flush logs,否则备份期间的DML/DDL会混入当前binlog文件,导致无法准确分离备份前/后变更;flush logs强制生成新binlog文件并从起始position开始写入,为后续mysqlbinlog恢复提供干净起点。

backup.sh 里不加 flush logs 会导致 binlog 定位失败
因为 mysqldump 备份本身不触发 binlog 切换,而后续基于时间点或 position 的恢复必须依赖一个「干净的起点」——即备份时刻之后的所有变更,都只落在新生成的 binlog 文件里。如果没执行 flush logs,mysqldump 备份期间产生的 DML/DDL 仍会写入当前正在使用的 binlog(比如 mysql-bin.000034),和更早的操作混在一起,导致你无法准确分离「备份前」和「备份后」的变更。
flush logs 不只是切换文件,它还重置了 position 计数
MySQL 的 binlog position 是连续递增的,即使跨文件也不重置。但 flush logs 会强制生成新文件并从 position 123(或类似小值)开始写入,而不是接着上一个文件末尾继续。这对后续用 mysqlbinlog --start-position 恢复至关重要:
- 未 flush:备份后第一个 insert 可能出现在
mysql-bin.000034的 position 897654,你得手动翻日志找这个位置 - 已 flush:备份后第一个操作必然在
mysql-bin.000035开头,直接从--start-position=123开始即可
Docker 环境下 flush logs 必须进容器执行
在宿主机直接连 MySQL 执行 flush logs 很可能失败,因为 Docker 容器里的 MySQL 实例默认只监听 127.0.0.1:3306,且 root 用户权限受限。正确做法是:
- 用
docker exec -it [容器名] mysql -u root -p -e "flush logs;" - 或把该命令写进 backup.sh,在
mysqldump命令之后、备份文件生成之前执行 - 注意:
flush logs需要RELOAD权限,确保备份用户有该权限(GRANT RELOAD ON *.* TO 'backup_user'@'%';)
容易被忽略的兼容性细节
MySQL 5.7 对 flush logs 的行为和权限要求比 8.0 更严格:
- 如果配置了
log_bin_trust_function_creators=OFF(默认),某些存储过程调用可能间接阻塞flush logs -
flush logs在复制环境中会同时刷新 relay log,若从库 IO 线程异常,可能报错ERROR 1201 (HY000): Could not initialize master info structure - 部分镜像(如
mysql:5.7.38)默认关闭log_error_verbosity,flush logs成功与否无明显日志,建议加&& echo "flush logs OK"辅助判断
真正麻烦的不是加一行命令,而是恢复时发现 position 对不上、时间点跳变、或者误删操作混在多个 binlog 里——这些几乎都源于备份脚本漏掉了 flush logs 这个看似无关紧要的动作。











