根本原因是IO线程默认只连接一次,必须启用GTID并显式设置AUTO_POSITION=1才能触发重试;slave_net_timeout需调至30或60以加快故障感知,且仅当连接建立后才生效。

主库重启后从库无法自动重连,根本原因不是“没开自动重连”,而是默认配置下 IO 线程只尝试连接一次,失败就停住,不触发后续重试 —— 这是 MySQL 复制机制的默认行为,不是 bug。
为什么 CHANGE MASTER TO 后只连一次就卡住
MySQL 从库的 IO 线程在启动时(START SLAVE)会尝试连接主库,但仅做一次连接动作。如果此时主库恰好正在重启、端口未监听或认证未就绪,IO 线程就会报错并停止,状态变为 Slave_IO_Running: No,且不会主动重试。
- 错误日志里常见:
The slave I/O thread stops because a fatal error is encountered或error connecting to master - 关键点:这个行为与
AUTO_POSITION是否启用无关;即使开了 GTID,只要没显式设置AUTO_POSITION = 1,依然只连一次 -
MASTER_CONNECT_RETRY参数只在“连接已建立但后续通信失败”时才起作用,对首次连接失败无效
必须设置 AUTO_POSITION = 1 才能触发重试逻辑
只有启用 GTID 并在 CHANGE MASTER TO 中明确指定 AUTO_POSITION = 1,IO 线程才会在连接失败后进入持续重试流程(否则它连重试入口都进不去)。
- 确认主库已开启
gtid_mode = ON且enforce_gtid_consistency = ON - 从库执行:
CHANGE MASTER TO MASTER_HOST='xxx', MASTER_USER='repl', MASTER_PASSWORD='xxx', AUTO_POSITION = 1;
- 检查生效:
SHOW SLAVE STATUS\G中Auto_Position字段必须为1 - 传统 binlog 文件+位置方式(
MASTER_LOG_FILE/MASTER_LOG_POS)永远不支持自动重连,这是硬限制
slave_net_timeout 是重连灵敏度的关键开关
这个参数控制 IO 线程等待主库响应的超时时间,它决定了“卡住多久才判定失败并触发重试”。设太大,主库刚重启完你得等一小时才重连;设太小,又容易把主库空闲期误判为故障。
- 默认值
3600(1 小时)完全不适合主库重启场景,必须调低 - 生产建议值:
30(跨机房/VPC)或60(同机房),执行:SET GLOBAL slave_net_timeout = 30;
- 修改后必须重启 IO 线程才生效:
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD; - 注意:
slave_net_timeout不影响首次连接,只影响连接建立后的读超时;但它决定了重试是否能及时发起
MASTER_CONNECT_RETRY 和 retry_count 需配合调整
这两个参数决定重试节奏和兜底能力,但它们的前提是 IO 线程已进入重试状态(即靠 AUTO_POSITION = 1 + slave_net_timeout 触发)。
-
MASTER_CONNECT_RETRY = 10:每次重试前等待 10 秒,避免密集握手冲击主库 -
retry_count(MySQL 8.0+):设为大值如86400,让线程近乎永久重试,防止某次网络抖动后彻底放弃 - 设置方式:
CHANGE MASTER TO MASTER_CONNECT_RETRY = 10;
(动态生效,无需重启线程) - 别依赖
MASTER_RETRY_COUNT:它只对连接被明确拒绝(如认证失败、端口不通)有效,对主库“暂时不可达”基本无用
最容易被忽略的一点:所有这些参数只对 IO 线程有效,SQL 线程断开(比如 relay log 损坏)不会自动恢复,得靠 relay_log_recovery = ON + master_info_repository = TABLE 加速重建;而主库重启后若 binlog 被清理,从库仍会卡在 Could not find first log file name in binary log index file,这时候光调参数没用,得人工补位或跳过。所以自动重连只是第一道防线,不能替代监控和人工预案。


















