用Docker搭建高可用MySQL主从集群,核心是容器网络互通、配置隔离与GTID复制协同:需创建自定义网络(如172.18.0.0/24),主从挂载独立conf/data/log目录,主库启用log-bin+GTID,从库设不同server-id+read_only+skip-slave-start=ON,启动后通过CHANGE MASTER TO MASTER_AUTO_POSITION=1配置复制,并验证Slave_IO_Running和Slave_SQL_Running均为Yes及Seconds_Behind_Master≈0。

用 Docker 搭建高可用 MySQL 主从集群,核心是让主库(Master)和至少一个从库(Slave)稳定通信、数据一致、故障可切换。它不依赖物理机配置,关键在容器网络、配置隔离、复制逻辑三者协同。下面分四步说清楚怎么做,每步都聚焦实操要点。
准备专用网络与目录结构
容器间必须能通过固定 IP 互访,不能靠默认桥接网络的动态地址。先创建自定义子网,并规划好宿主机挂载路径:
- 执行
docker network create --driver bridge --subnet=172.18.0.0/24 mysql-ha-net创建隔离网络 - 在宿主机建好目录树,例如:
mkdir -p /data/mysql/{master,slave1,slave2}/{conf,data,log} - 从官方镜像提取一份干净配置:
docker run --rm mysql:8.0 cat /etc/my.cnf > /data/mysql/master/conf/my.cnf,再复制到 slave1/slave2 对应目录
配置主库与从库参数
配置文件必须区分角色,且 server-id 全局唯一。不要直接改容器内文件,全部通过挂载方式管理:
-
主库 my.cnf(
/data/mysql/master/conf/my.cnf)加:[mysqld] server-id = 1 log-bin = mysql-bin binlog-format = ROW gtid-mode = ON enforce-gtid-consistency = ON skip-slave-start = OFF
-
从库 my.cnf(如
/data/mysql/slave1/conf/my.cnf)加:[mysqld] server-id = 2 log-bin = mysql-bin binlog-format = ROW gtid-mode = ON enforce-gtid-consistency = ON read_only = ON skip-slave-start = ON
(注意skip-slave-start=ON是为防止容器重启后自动拉取错误位点)
启动容器并初始化复制关系
用 docker run 启动,显式指定网络、IP 和挂载路径。主从启动顺序不强制,但复制配置需手动触发:
- 启动主库:
docker run -d --name mysql-master --network mysql-ha-net --ip 172.18.0.10 \<br> -v /data/mysql/master/conf:/etc/mysql/conf.d \<br> -v /data/mysql/master/data:/var/lib/mysql \<br> -v /data/mysql/master/log:/var/log/mysql \<br> -e MYSQL_ROOT_PASSWORD=root \<br> -e MYSQL_REPLICATION_USER=repl \<br> -e MYSQL_REPLICATION_PASSWORD=repl123 \<br> -p 3306:3306 \<br> mysql:8.0
- 启动从库(仅改 IP、名称、server-id、端口映射):
docker run -d --name mysql-slave1 --network mysql-ha-net --ip 172.18.0.11 \<br> -v /data/mysql/slave1/conf:/etc/mysql/conf.d \<br> -v /data/mysql/slave1/data:/var/lib/mysql \<br> -v /data/mysql/slave1/log:/var/log/mysql \<br> -e MYSQL_ROOT_PASSWORD=root \<br> -p 3307:3306 \<br> mysql:8.0
- 进主库创建复制用户(如果环境变量未自动创建):
docker exec -it mysql-master mysql -uroot -proot -e "CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl123'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;" - 查主库当前 GTID 位置:
docker exec mysql-master mysql -uroot -proot -e "SHOW MASTER STATUS\G" - 进从库执行 CHANGE MASTER TO:
docker exec -it mysql-slave1 mysql -uroot -proot -e "CHANGE MASTER TO MASTER_HOST='172.18.0.10', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='repl123', MASTER_AUTO_POSITION=1;" - 启动复制:
docker exec mysql-slave1 mysql -uroot -proot -e "START SLAVE;"
验证同步状态与基础高可用能力
光看容器 UP 不代表复制就通了。每次部署后必须检查三项指标:
- 执行
docker exec mysql-slave1 mysql -uroot -proot -e "SHOW SLAVE STATUS\G" | grep -E "(Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master)",确认两行都是Yes,延迟为0或个位数 - 主库建库写入:
docker exec mysql-master mysql -uroot -proot -e "CREATE DATABASE testdb; USE testdb; CREATE TABLE t1(id INT); INSERT INTO t1 VALUES(1);" - 从库立即查:
docker exec mysql-slave1 mysql -uroot -proot -e "SELECT * FROM testdb.t1;",应返回1 - 若需模拟主库宕机后的读服务连续性,可临时停主库:
docker stop mysql-master,再从应用层连从库查数据——此时它只读,但数据最新,这就是高可用的第一层意义


















