Docker可快速搭建一主一从MySQL集群,核心是确保CHANGE REPLICATION SOURCE TO成功及SHOW REPLICA STATUS中两线程均为Yes;需用官方镜像、正确配置binlog/GTID、统一自定义网络、容器名互访,并手动验证数据一致性和故障切换流程。

用 Docker 快速启动一主一从 MySQL 集群
不需要装包、改配置、开防火墙,Docker 是最轻量且可复现的高可用测试起点。关键不是“完全模拟生产”,而是让 CHANGE REPLICATION SOURCE TO 能跑通、SHOW REPLICA STATUS 能看到 Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes。
实操建议:
- 用官方
mysql:8.0镜像,避免第三方镜像默认关闭 binlog 或禁用 GTID - 主库必须启用
log-bin和server-id=1;从库设为server-id=2,且不能与主库重复 - 挂载自定义
my.cnf比用--extra-args更可靠,尤其涉及多行配置(如binlog-format=ROW) - 主从容器需在同一个自定义 bridge 网络里,否则
host.docker.internal不一定可达,建议用容器名互访(如主库容器名mysql-master,从库连它就填mysql-master)
docker network create mysql-ha-net docker run -d \ --name mysql-master \ --network mysql-ha-net \ -p 3307:3306 \ -v $(pwd)/master.cnf:/etc/mysql/conf.d/my.cnf \ -e MYSQL_ROOT_PASSWORD=123456 \ -d mysql:8.0 docker run -d \ --name mysql-slave \ --network mysql-ha-net \ -p 3308:3306 \ -v $(pwd)/slave.cnf:/etc/mysql/conf.d/my.cnf \ -e MYSQL_ROOT_PASSWORD=123456 \ -d mysql:8.0
手动配置主从复制时常见的连接失败原因
从库执行 CHANGE REPLICATION SOURCE TO 后报 ERROR 2003 (HY000): Can't connect to MySQL server 或 ERROR 2005 (HY000): Unknown MySQL server host,基本不是权限问题,而是网络或认证链路断了。
排查重点:
- 确认从库容器内能
ping mysql-master(同一 Docker 网络下应通) - 主库是否监听
0.0.0.0:3306?默认 MySQL 8.0 只绑127.0.0.1,需在my.cnf加bind-address = 0.0.0.0 - 主库是否创建了带
REPLICATION SLAVE权限的用户?注意 MySQL 8.0 必须用CREATE USER ... IDENTIFIED WITH caching_sha2_password,旧版mysql_native_password在某些客户端会握手失败 - 从库执行
CHANGE REPLICATION SOURCE TO时,SOURCE_HOST填的是主库容器名(如mysql-master),不是localhost或宿主机 IP
验证复制是否真正生效:别只看 SHOW REPLICA STATUS\G
Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 只说明线程在跑,不等于数据一致。容易忽略的验证点:
- 主库建库、建表、插入一行后,立刻在从库查:
SELECT COUNT(*) FROM test.t1—— 必须返回相同结果 - 检查
Seconds_Behind_Master是否稳定为0(偶尔抖动到 1–2 秒正常,持续 >5 秒要查 relay log 是否堆积) - 主库执行
FLUSH LOGS,再查SHOW MASTER STATUS,对比从库Relay_Master_Log_File是否同步到了最新 binlog 文件名 - 如果开启 GTID(推荐),主从
SELECT @@GLOBAL.GTID_EXECUTED应完全一致;不一致说明有事务被跳过或未执行
模拟故障:杀主库容器后如何让从库接管
Docker 环境无法自动选主,必须手动提升从库为新主库。这不是“高可用”的全部,但它是所有 HA 方案(MHA、Orchestrator、ProxySQL+consul)的基础动作。
操作顺序不能错:
- 先在原从库上执行
STOP REPLICA(MySQL 8.0.22+ 用STOP REPLICA,旧版是STOP SLAVE) - 再执行
RESET REPLICA ALL(清空复制元数据,包括master.info和relay-log.info) - 然后
SET GLOBAL read_only = OFF,否则应用写入会报错 - 最后确认
SELECT @@read_only返回OFF,才可把应用连接串指向该实例
注意:RESET REPLICA ALL 会删除 relay log 文件,不可逆;若后续还要拉另一个从库,得先在新主库上 FLUSH BINARY LOGS 并记下 SHOW MASTER STATUS 的起始位置。










