# Docker 搭建 MySQL 8 主从复制(踩坑实录 + 完整验证)

本文基于 Windows + Docker Desktop + MySQL 8

不是"命令堆砌教程",而是一篇 真实踩坑后总结的可落地实践文档


一、背景说明

在学习分布式系统和数据库高可用时,MySQL 主从复制是绕不开的基础能力。

很多教程看起来步骤简单,但实际操作中极容易遇到问题,例如:

  • Slave 一直 Connecting
  • 一写数据 Replica_SQL_Running 就变成 No
  • Last_Errno: 1049 Unknown database
  • 看起来都配对了,但就是不同步

本文记录了我使用 Docker 搭建 MySQL 主从复制的完整过程 + 排坑经验


二、整体架构

架构目标

  • 使用 Docker 启动两个 MySQL 8 容器
  • 一个作为 Master
  • 一个作为 Slave
  • Master 写入数据,Slave 自动同步

架构示意

复制代码
+------------------+        binlog        +------------------+
|   MySQL Master   |  ---------------->  |   MySQL Slave    |
|   server-id=1    |                     |   server-id=2    |
|   写 binlog      |                     |   回放 binlog    |
+------------------+                     +------------------+

三、环境准备

  • Windows 10 / 11
  • Docker Desktop(WSL2 后端)
  • PowerShell
  • MySQL 镜像:mysql:8.0

确认 Docker 正常:

powershell 复制代码
docker ps

四、创建 Docker 网络(非常关键)

❗ 主从容器必须在同一个 Docker 网络中

powershell 复制代码
docker network create mysql-net

验证:

powershell 复制代码
docker network ls

五、启动 MySQL Master

1️⃣ 启动容器

powershell 复制代码
docker run -d `
  --name master `
  --network mysql-net `
  -e MYSQL_ROOT_PASSWORD=root `
  -p 3306:3306 `
  mysql:8.0

参数说明

参数 作用
--network mysql-net 让 slave 可通过容器名访问
-p 3306:3306 本地调试方便

2️⃣ 进入 Master MySQL

powershell 复制代码
docker exec -it master mysql -uroot -p

3️⃣ 检查 Master 配置

sql 复制代码
SHOW VARIABLES LIKE 'server_id';
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';

期望结果:

  • server_id ≠ 0
  • log_bin = ON
  • binlog_format = ROW

Docker 官方 MySQL 8 镜像默认已开启 binlog


4️⃣ 创建复制账号

sql 复制代码
CREATE USER 'reader'@'%' IDENTIFIED BY 'reader';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'reader'@'%';
FLUSH PRIVILEGES;

5️⃣ 获取 binlog 位点(非常重要)

sql 复制代码
SHOW MASTER STATUS;

示例:

复制代码
File: mysql-bin.000003
Position: 881

必须记录这两个值


六、启动 MySQL Slave

1️⃣ 启动容器

powershell 复制代码
docker run -d `
  --name slave `
  --network mysql-net `
  -e MYSQL_ROOT_PASSWORD=root `
  -p 3307:3306 `
  mysql:8.0

2️⃣ 进入 Slave MySQL

powershell 复制代码
docker exec -it slave mysql -uroot -p

3️⃣ 配置复制源(MySQL 8 写法)

sql 复制代码
STOP REPLICA;

CHANGE REPLICATION SOURCE TO
  SOURCE_HOST = 'master',
  SOURCE_PORT = 3306,
  SOURCE_USER = 'reader',
  SOURCE_PASSWORD = 'reader',
  SOURCE_LOG_FILE = 'mysql-bin.000003',
  SOURCE_LOG_POS = 881;

START REPLICA;

4️⃣ 查看复制状态

sql 复制代码
SHOW REPLICA STATUS\G

正常状态:

复制代码
Replica_IO_Running: Yes
Replica_SQL_Running: Yes

七、一个必踩的大坑(重点)

❗ 问题现象

  • 主库创建表

  • 从库 Replica_SQL_Running 直接变 No

  • 报错:

    Last_Errno: 1049
    Unknown database 'test_sync'


❗ 原因分析(非常重要)

binlog 会同步 SQL,而不是帮你创建数据库

  • Master 中执行了:

    sql 复制代码
    USE test_sync;
    CREATE TABLE ...
  • Slave 中并不存在 test_sync 这个数据库

  • SQL 回放失败,复制线程停止


✅ 正确解决方式

只在 Slave 上创建数据库(不要建表)

sql 复制代码
CREATE DATABASE test_sync;
START REPLICA;

八、数据同步验证流程

1️⃣ 在 Master 操作数据

sql 复制代码
CREATE DATABASE test_sync;
USE test_sync;

CREATE TABLE t_user (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(64),
  age INT
);

INSERT INTO t_user(username, age) VALUES ('alice', 18);

2️⃣ 在 Slave 验证

sql 复制代码
USE test_sync;
SELECT * FROM t_user;

如果能看到数据:

复制代码
+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | alice    |  18 |
+----+----------+-----+

🎉 主从复制成功


九、常见问题排查总结

1️⃣ Replica_IO_Running: Connecting

原因:

  • 不在同一个 Docker 网络
  • SOURCE_HOST 写成 localhost
  • 端口错误

验证网络:

powershell 复制代码
docker inspect master --format "{{json .NetworkSettings.Networks}}"
docker inspect slave  --format "{{json .NetworkSettings.Networks}}"

2️⃣ Replica_SQL_Running: No

原因:

  • 数据库不存在
  • 表结构冲突
  • 手动在 Slave 建过表

排错命令:

sql 复制代码
SHOW REPLICA STATUS\G
SELECT * 
FROM performance_schema.replication_applier_status_by_worker\G;

十、总结

✔ Docker + MySQL 主从并不复杂

❌ 难点在 细节和顺序

关键点总结:

  • 主从必须同一 Docker 网络
  • Slave 不会自动建库
  • 只在 Master 写数据
  • 错误一定要看 Last_Error

相关推荐
qq_316837752 小时前
docker 运行 cn_clip
运维·docker·容器
占疏2 小时前
数据库-BRIN 索引
数据库·mysql
木卫二号Coding3 小时前
Docker-构建自己的Web-Linux系统-Ubuntu:22.04
linux·前端·docker
春日见3 小时前
win11 分屏设置
java·开发语言·驱动开发·docker·单例模式·计算机外设
岳来3 小时前
网络小白理解容器网络endpointid
网络·docker·endpoint
江湖有缘4 小时前
轻量级知识协作平台搭建:Docker + MediaWiki入门教程
docker·容器·eureka
heze094 小时前
sqli-labs-Less-28a
数据库·mysql·网络安全
Genie cloud4 小时前
在 Mac 上使用 Docker 安装宝塔并部署 LNMP 环境
macos·docker·容器·云计算
无限码力4 小时前
华为OD技术面真题 - 数据库MySQL - 3
数据库·mysql·华为od·八股文·华为od技术面八股文