Docker 环境下 MySQL 一主一从同步实战
·
Docker 环境下 MySQL 一主一从同步实战
前言
在实际开发与生产场景中,MySQL 单节点往往无法满足高可用、高并发以及数据备份的需求。主从复制作为 MySQL 最经典的高可用方案,能够实现读写分离、故障转移与数据冗余备份。
本文将基于 Docker 容器化环境,使用 MySQL 8.3.0 版本快速搭建一主一从架构,全程通过自动化 Shell 脚本实现部署,无需手动修改复杂配置文件,可复现、易维护,非常适合学习与测试环境使用。
一、环境说明
- 操作系统:Windows + WSL2
- 容器引擎:Docker
- MySQL 版本:8.3.0
- 主库端口:3307
- 从库端口:3308
- root 密码:123456
- 复制账号:repl / 123456
二、主从复制原理简述
-
主库(Master)
- 开启二进制日志
binlog,所有数据变更都会记录到 binlog 中。 - 为 IO 线程提供 binlog 读取权限。
- 开启二进制日志
-
从库(Slave)
- IO 线程:连接主库,请求并接收 binlog,写入中继日志
relay log。 - SQL 线程:读取中继日志,重放 SQL 语句,实现数据同步。
- IO 线程:连接主库,请求并接收 binlog,写入中继日志
三、一键部署脚本
为了简化部署流程,避免手动配置出错,编写自动化 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🎉 部署成功!"
四、脚本执行步骤
- 赋予脚本执行权限
bash
运行
chmod +x mysql_ms_deploy.sh
- 运行脚本
bash
运行
./mysql_ms_deploy.sh
- 等待执行完成,出现以下结果表示主从同步正常:
plaintext
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
五、主从同步测试
- 主库写入数据
bash
运行
docker exec mysql-master mysql -uroot -p123456 -e "CREATE DATABASE testdb; USE testdb; CREATE TABLE user(id INT); INSERT INTO user VALUES(1);"
- 从库查询验证
bash
运行
docker exec mysql-slave mysql -uroot -p123456 -e "SELECT * FROM testdb.user;"
若能正常查询到数据,说明主从复制搭建成功。
六、常见问题与排错
-
Slave_IO_Running: Connecting
- 主从网络不通
- 复制账号密码错误
- 主库 binlog 未正常开启
-
Slave_SQL_Running: No
- 主从数据不一致
- 从库执行 SQL 报错
- 跳过事务可临时修复:
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
-
Docker 镜像拉取失败
- 更换镜像加速源
- 执行
docker system prune -a清理缓存
项目配置演示:

七、总结
通过 Docker 可以快速、干净地部署 MySQL 主从架构,避免了传统安装方式的环境污染与复杂配置。本文提供的一键脚本自动完成:
- 容器创建与端口映射
- server-id、binlog、relay-log 配置
- 复制账号创建
- 从库自动指向主库
- 状态自动检查
整套方案可直接用于学习、测试与演示,也可在此基础上扩展为 MGR、半同步复制、读写分离等更高级架构。
更多推荐
所有评论(0)