Windows 环境下使用 Docker 搭建 MySQL 8 一主两从指南
本文档基于 Windows + Docker Desktop + MySQL 8 官方镜像 的真实踩坑过程整理,
适合:后端开发 / 学习 MySQL 主从 / 本地模拟生产环境。
一、目标架构
- 1 个主库(mysql-master)
- 2 个从库(mysql-slave1 / mysql-slave2)
- 使用 GTID + AUTO_POSITION
- Docker Compose 一键启动
mysql-master (server-id=1)
│
├── mysql-slave1 (server-id=2)
└── mysql-slave2 (server-id=3)
二、核心原则(非常重要)
Windows 下必须遵守的 3 条原则
- 不要挂载 conf.d(否则 MySQL 会忽略配置)
- MySQL 配置全部写在 command 里
- 修改配置后必须
docker compose down -v
原因:
- Windows bind mount 的目录权限是 777
- MySQL 8 会直接忽略 world-writable 的 cnf 文件
- 导致:
server_id=1、gtid_mode=OFF永远改不掉
三、完整 docker-compose.yml(最终可用版)
version: "3.8"
services:
mysql-master:
image: mysql:8.0
container_name: mysql-master
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
command:
[
"mysqld",
"--default-authentication-plugin=mysql_native_password",
"--server-id=1",
"--log-bin=mysql-bin",
"--binlog-format=ROW",
"--gtid-mode=ON",
"--enforce-gtid-consistency=ON"
]
volumes:
- mysql-master-data:/var/lib/mysql
networks:
- mysql-net
mysql-slave1:
image: mysql:8.0
container_name: mysql-slave1
restart: always
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
depends_on:
- mysql-master
command:
[
"mysqld",
"--default-authentication-plugin=mysql_native_password",
"--server-id=2",
"--gtid-mode=ON",
"--enforce-gtid-consistency=ON",
"--relay-log=relay-bin",
"--log-slave-updates=ON",
"--read-only=ON"
]
volumes:
- mysql-slave1-data:/var/lib/mysql
networks:
- mysql-net
mysql-slave2:
image: mysql:8.0
container_name: mysql-slave2
restart: always
ports:
- "3308:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
depends_on:
- mysql-master
command:
[
"mysqld",
"--default-authentication-plugin=mysql_native_password",
"--server-id=3",
"--gtid-mode=ON",
"--enforce-gtid-consistency=ON",
"--relay-log=relay-bin",
"--log-slave-updates=ON",
"--read-only=ON"
]
volumes:
- mysql-slave2-data:/var/lib/mysql
networks:
- mysql-net
networks:
mysql-net:
driver: bridge
volumes:
mysql-master-data:
mysql-slave1-data:
mysql-slave2-data:
四、启动步骤(顺序不能错)
docker compose down -v
docker compose up -d
-v必须加,否则 MySQL 会继续使用旧数据目录,配置不会生效
等待日志出现:
ready for connections
五、登录注意事项(MySQL 8 坑点)
错误方式
mysql -uroot -p123456
报错:
Access denied for user 'root'@'localhost'
正确方式(强制 TCP)
docker exec -it mysql-slave1 mysql -uroot -p123456 -h127.0.0.1
原因:
- MySQL 8 官方镜像默认只有
root@'%' - socket 登录等于
root@localhost
六、验证基础配置
在 slave 上:
SHOW VARIABLES LIKE 'server_id';
SHOW VARIABLES LIKE 'gtid_mode';
期望结果:
server_id = 2/3
gtid_mode = ON
七、创建复制用户(主库)
CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
八、配置从库复制(GTID)
在 slave1 / slave2:
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='mysql-master',
SOURCE_USER='repl',
SOURCE_PASSWORD='123456',
SOURCE_AUTO_POSITION=1;
START REPLICA;
九、常见错误 & 解决方案汇总
1. ERROR 1200: The server is not configured as replica
原因:
server_id未生效- 配置文件被忽略
解决:
- 不挂载 conf.d
- 使用 command
docker compose down -v
2. ERROR 1777: GTID_MODE = OFF
原因:
- gtid_mode 未真正生效
解决:
- 确认 command 中包含
--gtid-mode=ON - 删除 volume 重新启动
3. Replica_IO_Running: Connecting
原因:
- master 尚未 ready
- 复制用户不存在
解决:
STOP REPLICA;
RESET REPLICA ALL;
-- 重新 CHANGE REPLICATION SOURCE TO
4. conf.d 提示被忽略
World-writable config file ... is ignored
原因:Windows 挂载权限问题
解决:完全不用 conf.d
十、最终成功标志
SHOW REPLICA STATUS\G
看到:
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
十一、实锤验证复制
主库:
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO t1 VALUES (1,'ok');
从库:
SELECT * FROM test_db.t1;
十二、总结
- 这是 Windows Docker 下 MySQL 主从的正确姿势
- 避开了 90% 网络教程的坑
- 可直接作为:
- 本地开发环境
- 学习主从复制
- 面试演示项目