Orchestrator 不自动执行 CHANGE MASTER TO,因其设计为“观测+协调”而非“代理+执行”,所有写操作交由外部钩子完成以确保安全隔离与审计可控。

Orchestrator 本身不直接执行 MySQL 主从切换,它只做决策和调用脚本;真正的切换动作必须由你写的 raft 或 external 模式下的自定义钩子(hook)完成,否则只会卡在“候选中”状态。
为什么 orchestrator 不自动执行 CHANGE MASTER TO?
Orchestrator 的设计哲学是“观测 + 协调”,不是“代理 + 执行”。它通过 SHOW SLAVE STATUS 和 SELECT @@global.gtid_executed 等判断拓扑状态,但所有写操作(如 STOP SLAVE、RESET SLAVE、CHANGE MASTER TO)都交由外部脚本处理——这是为了安全隔离和审计可控。
- 默认配置下,
FailureDetectionPeriodSeconds设为 30 秒,但实际故障发现可能延迟 2–3 个探测周期(取决于BackendDB健康检查频率) - 若启用
RecoverMaster,orchestrator 仅会尝试将原主库降级为从库,不会自动提升新主;必须靠PostGracefulTakeoverProcesses钩子触发 DNS/VIP 切换或应用层重路由 - GTID 模式下,
BinlogServer或BinlogSource配置错误会导致FindSlavesThatAreBetterCandidates误判,跳过真正延迟低的节点
PreFailoverProcesses 和 PostFailoverProcesses 怎么写才可靠?
这两个钩子是故障切换成败的关键。orchestrator 在调用前会传入环境变量:ORC_INSTANCE_ALIAS(故障实例别名)、ORC_CANDIDATE_INSTANCE_ALIAS(候选主库别名)、ORC_IS_MASTER_FAILURE(是否主库宕机)等,脚本必须基于这些做分支判断。
- 推荐用 Bash +
mysqlCLI 调用,避免 Python/Go 脚本引入额外依赖和超时风险 -
PreFailoverProcesses示例任务:检查候选库Seconds_Behind_Master <= 5、确认Executed_Gtid_Set包含故障主库的全部事务、停掉中间件写连接(如 ProxySQL 的UPDATE mysql_servers) -
PostFailoverProcesses必须包含:对新主执行SET GLOBAL read_only = OFF、更新 Consul/Etcd 中的/mysql/masterKV、发送 Slack 告警(含ORC_FAILING_INSTANCE和ORC_SUCCESSOR_INSTANCE) - 所有 SQL 操作需加
--connect-timeout=5 --execution-timeout=10,防止挂起阻塞整个 failover 流程
常见失败场景与对应日志关键词
当切换卡住或回滚,先查 orchestrator 日志(默认 /var/log/orchestrator/orchestrator.log),重点关注带 failover、candidate、hook 的行:
-
Failed to execute PreFailoverProcesses: exit status 1→ 检查钩子脚本权限(需可执行)、是否 echo 了非空输出(orchestrator 把 stdout 当错误信息捕获) -
No candidate found for master failure→ 确认所有从库开启了log_slave_updates,且orchestrator用户有REPLICATION CLIENT权限 -
Topology instance is not writable→ 新主库的read_only=ON未被钩子关闭,或 MySQL 8.0+ 下super_read_only仍为 ON -
Cannot resolve hostname→ orchestrator 配置中HostnameResolveMethod设为none,但钩子脚本里硬编码了 IP,导致后续拓扑刷新失败
最易被忽略的是:orchestrator 的 raft 模式要求所有节点时间误差 chronyd 同步),否则 Leader 频繁漂移,failover 请求会被拒绝;另外,MySQL 5.7 的 relay_log_recovery=ON 可能导致切换后从库无法追平,建议设为 OFF 并配合 relay_log_purge=ON。


















