用 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的起始位置。
