MySQL主从切换备份恢复失效主因是GTID与binlog配置不匹配,需用--set-gtid-purged=OFF、STOP SLAVE后再恢复,并统一sql_mode、字符集及my.cnf参数。

MySQL主从切换时备份恢复测试不生效?先确认 binlog 格式和 GTID 状态
容灾演练失效,八成卡在备份与恢复的“时间线对不上”——比如用 mysqldump 备份时没带 --set-gtid-purged=OFF,又开了 gtid_mode=ON,恢复后从库直接报 ERROR 1236 (HY000): The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.。
实操建议:
- 检查当前配置:
SELECT @@binlog_format, @@gtid_mode;—— 若是STATEMENT或OFF,mysqldump默认不写 GTID;若是ROW+ON,必须显式控制--set-gtid-purged - 生产备份命令应固定为:
mysqldump --single-transaction --routines --triggers --databases db1 db2 --set-gtid-purged=OFF > backup.sql - 恢复前务必停掉从库复制:
STOP SLAVE;,再source backup.sql,否则可能触发冲突或跳过部分事务
用 mysqlpump 替代 mysqldump 做并行备份恢复测试?注意权限和字符集兼容性
mysqlpump 虽支持多线程、更易读的输出,但默认不导出 CREATE DATABASE 语句,也不保证跨 MySQL 版本的字符集兼容——比如 5.7 备份中含 utf8mb4_0900_as_cs 排序规则,在 8.0.22 以下版本恢复会报错 Unknown collation: 'utf8mb4_0900_as_cs'。
实操建议:
- 加
--include-databases显式指定库,避免漏掉CREATE DATABASE;用--default-character-set=utf8mb4统一编码上下文 - 若目标环境是 MySQL 5.7,备份时加
--skip-definer和--skip-triggers(触发器定义语法有差异) - 不要依赖
mysqlpump的--defer-table-indexes在恢复时提速——它在含外键的库上容易因索引延迟导致ERROR 1215
恢复测试总卡在“表不存在”或“列类型不匹配”?检查备份时的 SQL 模式和严格模式
同一个 backup.sql 在开发机恢复成功,放到测试环境却报 ERROR 1175: You are using safe update mode... 或 ERROR 1366: Incorrect string value,大概率是两边 sql_mode 不一致。MySQL 5.7 默认启用 STRICT_TRANS_TABLES,而 5.6 或某些 Docker 镜像默认关着。
实操建议:
- 备份前统一设置:
SET sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';,并在 dump 文件开头加注释说明 - 恢复脚本开头强制重置:
SET sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'; SOURCE backup.sql; - 别信
mysqldump --compatible=mysql40这种参数——它只改语法糖,不解决底层类型兼容(如JSON字段在 5.7+ 才原生支持)
自动化定期恢复测试脚本跑不通?重点盯住临时目录权限和 socket 路径
写完 Bash 脚本自动拉取最新备份、启临时实例、导入、校验,结果卡在 Can't connect to local MySQL server through socket '/tmp/mysql.sock' 或 Permission denied: /var/lib/mysql-test——不是逻辑问题,是环境细节没对齐。
实操建议:
- 临时实例必须用
--socket=/tmp/mysql_test.sock显式指定路径,避免和线上实例冲突;且该路径所在目录需chown -R mysql:mysql /tmp/mysql_test_data - 用
mysql --defaults-file=代替-u -p,把密码写进临时配置文件并chmod 600,否则脚本里明文密码会被ps aux看见 - 校验环节别只查
SELECT COUNT(*),加一条SELECT MIN(id), MAX(id), COUNT(*) FROM t1;—— 能暴露自增 ID 断层、误删等静默错误
真正难的不是写脚本,是每次恢复测试前手动核对 my.cnf 里 innodb_log_file_size 是否和备份生成时一致——差 1MB 就会导致启动失败,但错误日志只说 InnoDB: Database page corruption on disk,不提具体原因。











