MySQL 8.0 崩溃安全复制需同时满足:启用 binlog(log_bin=ON、binlog_format=ROW)、relay_log_info_repository=TABLE(且 mysql.slave_relay_log_info 为 InnoDB 表)、sync_relay_log=1;GTID 强烈推荐开启(gtid_mode=ON、enforce_gtid_consistency=ON),server_id 必须全局唯一非零。

MySQL 8.0 默认已启用崩溃安全复制(Crash-Safe Replication),但必须同时满足两个前提:启用 binlog + 设置 relay_log_info_repository = TABLE + 启用 sync_relay_log = 1。缺一不可,否则主从切换后可能丢事务或重复执行。
确认 binlog 和 GTID 是否已开启
崩溃安全复制依赖 binlog 重放和 relay log 位置的持久化记录,不开启 binlog 就根本无法做复制;而 GTID 虽非强制,但强烈建议启用——它让故障恢复时无需手动找 position,避免误操作。
-
binlog必须在主从两端都启用:log_bin = ON,且binlog_format = ROW(MIXED或STATEMENT在某些场景下无法保证一致性) - 检查是否启用 GTID:
SELECT @@gtid_mode;应返回ON;若为OFF,需在配置中加gtid_mode = ON和enforce_gtid_consistency = ON,并重启 -
server_id必须全局唯一,且不能为 0(常见错误:多实例共用默认server_id = 1)
必须把 relay log 元数据存到表里
MySQL 5.6 引入 relay_log_info_repository,用于决定 relay log 读取位置(即 SQL 线程执行到哪条 event)存在哪。默认是 FILE(写入 relay-log.info 文件),但该文件不会随事务一起刷盘,崩溃后容易丢失最新位置,导致重复执行或跳过事件。
- 必须设为
TABLE:relay_log_info_repository = TABLE - 对应表是
mysql.slave_relay_log_info,引擎必须为InnoDB(确保事务安全) - 确认该表存在且可写:
SELECT * FROM mysql.slave_relay_log_info\G;若为空或报错,说明配置未生效或权限不足
同步 relay log 写入与刷盘策略
即使元数据存表,如果 relay log 文件本身没及时落盘,SQL 线程仍可能读到不完整 event,引发解析失败或数据错乱。关键参数是 sync_relay_log 和 sync_relay_log_period。
-
sync_relay_log = 1表示每次写入一个 event 就fsync()一次(最安全,性能略低);设为 0 则依赖 OS 缓存,崩溃易丢日志 -
sync_relay_log_period = 10000(默认)仅在sync_relay_log > 0时生效,表示每 N 次写入后才刷盘;所以sync_relay_log = 1时该值无意义 - 配套建议:
innodb_flush_log_at_trx_commit = 1(保证事务日志落盘)、sync_binlog = 1(主库 binlog 安全)
验证是否真正 crash-safe
配置改完不等于生效,尤其 relay_log_info_repository = TABLE 这类动态变量在 MySQL 8.0 中部分需重启才生效(取决于版本补丁)。最可靠的方式是模拟断电式中断并检查状态。
- 主动 kill -9
mysqld进程(不要用mysqladmin shutdown) - 重启后执行:
SHOW SLAVE STATUS\G,重点看Relay_Log_File和Relay_Log_Pos是否与mysql.slave_relay_log_info表中一致 - 再查
Retrieved_Gtid_Set和Executed_Gtid_Set是否连续、无空洞(GTID 模式下这是更本质的校验) - 常见翻车点:
slave_parallel_workers > 0时若未配slave_preserve_commit_order = ON,可能导致 GTID 提交顺序错乱,间接破坏 crash-safe 语义
真正麻烦的不是配置项本身,而是多个参数之间的隐含依赖关系——比如开了 GTID 却没设 enforce_gtid_consistency,或者 relay_log_info_repository = TABLE 但 mysql.slave_relay_log_info 表被意外删掉或引擎改成 MyISAM,这些都会让崩溃安全形同虚设。


















