Docker 环境下 MySQL  一主一从同步实战

前言

在实际开发与生产场景中,MySQL 单节点往往无法满足高可用、高并发以及数据备份的需求。主从复制作为 MySQL 最经典的高可用方案,能够实现读写分离、故障转移与数据冗余备份。

本文将基于 Docker 容器化环境,使用 MySQL 8.3.0 版本快速搭建一主一从架构,全程通过自动化 Shell 脚本实现部署,无需手动修改复杂配置文件,可复现、易维护,非常适合学习与测试环境使用。

一、环境说明

  • 操作系统:Windows + WSL2
  • 容器引擎:Docker
  • MySQL 版本:8.3.0
  • 主库端口:3307
  • 从库端口:3308
  • root 密码:123456
  • 复制账号:repl / 123456

二、主从复制原理简述

  1. 主库(Master)

    • 开启二进制日志 binlog,所有数据变更都会记录到 binlog 中。
    • 为 IO 线程提供 binlog 读取权限。
  2. 从库(Slave)

    • IO 线程:连接主库,请求并接收 binlog,写入中继日志 relay log
    • SQL 线程:读取中继日志,重放 SQL 语句,实现数据同步。

三、一键部署脚本

为了简化部署流程,避免手动配置出错,编写自动化 Shell 脚本 mysql_ms_deploy.sh

bash

运行

#!/bin/bash

# ====================== MySQL 8.3.0 主从一键脚本 ======================
# 主库:3307    从库:3308    密码:123456
# ======================================================================

echo "============================================="
echo "     MySQL 8.3.0 Master-Slave Deploy"
echo "     Master: 3307 | Slave: 3308"
echo "     Password: 123456"
echo "============================================="

# 1. 清理旧容器
echo -e "\n[1/6] 清理旧容器..."
docker rm -f mysql-master mysql-slave >/dev/null 2>&1

# 2. 启动主库
echo -e "\n[2/6] 启动主库(3307)..."
docker run -d --name mysql-master \
  -p 3307:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.3.0 \
  --server-id=1 \
  --log-bin=mysql-bin \
  --binlog-format=ROW

# 3. 启动从库
echo -e "\n[3/6] 启动从库(3308)..."
docker run -d --name mysql-slave \
  -p 3308:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.3.0 \
  --server-id=2 \
  --relay-log=relay-bin

# 4. 等待MySQL启动
echo -e "\n[4/6] 等待MySQL启动 15秒..."
sleep 15

# 5. 创建同步账号
echo -e "\n[5/6] 创建同步账号 repl..."
docker exec mysql-master mysql -uroot -p123456 -e "
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
" 2>/dev/null

# 6. 获取主库信息并配置从库
echo -e "\n[6/6] 配置主从同步..."
file=$(docker exec mysql-master mysql -uroot -p123456 -N -e "SHOW MASTER STATUS;" 2>/dev/null | awk '{print $1}')
pos=$(docker exec mysql-master mysql -uroot -p123456 -N -e "SHOW MASTER STATUS;" 2>/dev/null | awk '{print $2}')
master_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql-master)

docker exec mysql-slave mysql -uroot -p123456 -e "
STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO
  MASTER_HOST='$master_ip',
  MASTER_USER='repl',
  MASTER_PASSWORD='123456',
  MASTER_LOG_FILE='$file',
  MASTER_LOG_POS=$pos;
START SLAVE;
" 2>/dev/null

# 输出结果
echo -e "\n============================================="
echo "✅ 部署完成!"
echo "主库:localhost:3307   root / 123456"
echo "从库:localhost:3308   root / 123456"
echo -e "=============================================\n"

echo "🔍 从库同步状态:"
docker exec mysql-slave mysql -uroot -p123456 -e "SHOW SLAVE STATUS\G" 2>/dev/null | grep "Slave_IO_Running\|Slave_SQL_Running"

echo -e "\n🎉 部署成功!"

四、脚本执行步骤

  1. 赋予脚本执行权限

bash

运行

chmod +x mysql_ms_deploy.sh
  1. 运行脚本

bash

运行

./mysql_ms_deploy.sh
  1. 等待执行完成,出现以下结果表示主从同步正常:

plaintext

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

五、主从同步测试

  1. 主库写入数据

bash

运行

docker exec mysql-master mysql -uroot -p123456 -e "CREATE DATABASE testdb; USE testdb; CREATE TABLE user(id INT); INSERT INTO user VALUES(1);"
  1. 从库查询验证

bash

运行

docker exec mysql-slave mysql -uroot -p123456 -e "SELECT * FROM testdb.user;"

若能正常查询到数据,说明主从复制搭建成功。

六、常见问题与排错

  1. Slave_IO_Running: Connecting

    • 主从网络不通
    • 复制账号密码错误
    • 主库 binlog 未正常开启
  2. Slave_SQL_Running: No

    • 主从数据不一致
    • 从库执行 SQL 报错
    • 跳过事务可临时修复:SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
  3. Docker 镜像拉取失败

    • 更换镜像加速源
    • 执行 docker system prune -a 清理缓存

项目配置演示:

七、总结

通过 Docker 可以快速、干净地部署 MySQL 主从架构,避免了传统安装方式的环境污染与复杂配置。本文提供的一键脚本自动完成:

  • 容器创建与端口映射
  • server-id、binlog、relay-log 配置
  • 复制账号创建
  • 从库自动指向主库
  • 状态自动检查

整套方案可直接用于学习、测试与演示,也可在此基础上扩展为 MGR、半同步复制、读写分离等更高级架构。

更多推荐