Docker 高可用实战:MySQL 主从复制(Master-Slave)搭建指南
在微服务架构中,数据库的高可用 与读写分离是保障系统稳定性的关键。MySQL 主从复制通过将主库(Master)的数据实时同步到从库(Slave),实现:
- ✅ 数据冗余:主库故障时快速切换
- ✅ 负载均衡:读请求分发到从库,减轻主库压力
- ✅ 备份保障:从库可作为热备份
本文将手把手教你用 Docker 搭建 MySQL 5.7 主从集群,并解决网络配置、权限设置等常见陷阱。
环境说明:
- 宿主机 IP:
192.168.100.6(需替换为你的实际 IP)- 主库端口:
3306- 从库端口:
3307- MySQL 镜像:私有仓库
192.168.100.50:5000/mysql:5.7
一、主库(Master)搭建
步骤 1:创建目录结构
bash
mkdir -p /opt/mysql/master/{data,log,conf}
步骤 2:启动主库容器
bash
docker run -d \
-p 3306:3306 \
-v /opt/mysql/master/log:/var/log/mysql \
-v /opt/mysql/master/data:/var/lib/mysql \
-v /opt/mysql/master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=000000 \
--name mysqlmaster1 \
192.168.100.50:5000/mysql:5.7
步骤 3:配置主库参数
编辑 /opt/mysql/master/conf/my.cnf:
ini
[mysqld]
# 唯一服务器ID(主从必须不同)
server_id=1
# 启用二进制日志(复制的核心)
log_bin=mysql-bin
# 可选:指定要同步的数据库(不配置则同步所有)
# binlog_do_db=test_db
⚠️ 关键参数:
server_id:集群内唯一标识log_bin:开启二进制日志,记录所有写操作
重启生效:
bash
docker restart mysqlmaster1
步骤 4:创建复制专用用户
bash
# 进入主库
docker exec -it mysqlmaster1 mysql -uroot -p000000
# 创建用户并授权
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '000000';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
mysql> FLUSH PRIVILEGES;
🔒 安全建议:
- 限制从库 IP:
'slave'@'192.168.100.%'- 使用强密码(非
000000)
步骤 5:记录主库状态(用于从库配置)
sql
mysql> SHOW MASTER STATUS\G
*************************** 1. row ***************************
File: mysql-bin.000005
Position: 684
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
记下 File 和 Position,后续从库配置需要!
二、从库(Slave)搭建
步骤 1:创建目录结构
bash
mkdir -p /opt/mysql/slave/{data,log,conf}
步骤 2:启动从库容器
bash
docker run -d \
-p 3307:3306 \ # 映射到宿主机3307端口
-v /opt/mysql/slave/data:/var/lib/mysql \
-v /opt/mysql/slave/log:/var/log/mysql \
-v /opt/mysql/slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=000000 \
--name mysqlslave \
192.168.100.50:5000/mysql:5.7
步骤 3:配置从库参数
编辑 /opt/mysql/slave/conf/my.cnf:
ini
[mysqld]
# 唯一服务器ID(与主库不同)
server_id=2
# 从库只读(防止误写)
read_only=1
# 可选:跳过错误(谨慎使用)
# slave_skip_errors=1062
重启生效:
bash
docker restart mysqlslave
步骤 4:配置主从连接
bash
# 进入从库
docker exec -it mysqlslave mysql -uroot -p000000
# 执行 CHANGE MASTER TO(关键步骤!)
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.100.6', -- 宿主机IP(非容器IP!)
MASTER_PORT=3306, -- 主库端口
MASTER_USER='slave', -- 复制用户名
MASTER_PASSWORD='000000', -- 密码
MASTER_LOG_FILE='mysql-bin.000005', -- 主库File值
MASTER_LOG_POS=684, -- 主库Position值
MASTER_CONNECT_RETRY=30; -- 重连间隔(秒)
# 启动复制进程
mysql> START SLAVE;
🌐 网络关键点:
MASTER_HOST必须是宿主机 IP(因从库容器需访问宿主机暴露的 3306 端口)- 若主从在同一 Docker 网络,可用容器名(见文末优化方案)
步骤 5:验证复制状态
sql
mysql> SHOW SLAVE STATUS\G
成功标志:
text
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0 -- 延迟为0
❌ 常见错误:
Slave_IO_Running: Connecting→ 网络不通或账号密码错误Slave_SQL_Running: No→ SQL 执行错误(如主键冲突)
三、功能测试:验证数据同步
在主库操作
sql
-- 创建数据库和表
CREATE DATABASE test1;
USE test1;
CREATE TABLE t1(id INT, name VARCHAR(8));
INSERT INTO t1 VALUES(1, 'zs');
SELECT * FROM t1;
在从库验证
sql
-- 查看数据库
SHOW DATABASES; -- 应包含 test1
-- 查询数据
USE test1;
SELECT * FROM t1; -- 应显示 (1, 'zs')
✅ 同步成功!所有写操作均实时复制到从库。
四、高级优化与故障处理
优化 1:使用 Docker 自定义网络(避免宿主机 IP 依赖)
bash
# 创建专用网络
docker network create mysql-net
# 重新启动主从(加入网络)
docker run -d --network mysql-net --name master ...
docker run -d --network mysql-net --name slave ...
# 从库配置时直接用容器名
CHANGE MASTER TO MASTER_HOST='master', ...;
优化 2:半同步复制(增强数据安全)
在主库启用半同步插件:
sql
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
故障处理:主库宕机后提升从库为主库
-
停止从库复制:
sqlSTOP SLAVE; RESET MASTER; -
修改应用配置指向新主库(原从库)
-
修复原主库后,将其作为新从库加入
五、生产环境 checklist
| 项目 | 检查点 |
|---|---|
| 网络 | 主从能否互相访问?防火墙是否开放端口? |
| 权限 | 复制用户是否仅限从库 IP?密码是否足够强? |
| 监控 | 是否监控 Seconds_Behind_Master 延迟? |
| 备份 | 是否定期备份主库?从库是否可快速切换? |
| 日志 | 二进制日志是否定期清理?(避免磁盘占满) |
六、总结
通过 Docker 搭建 MySQL 主从复制,你已掌握:
- 主库配置:启用二进制日志 + 创建复制用户
- 从库配置:设置只读 + 关联主库
- 验证方法 :
SHOW SLAVE STATUS+ 数据测试
🚀 下一步行动:
- 结合 Keepalived 实现 VIP 自动漂移
- 使用 ProxySQL 实现读写分离
- 迁移到 MySQL 8.0 并启用 GTID 复制
主从复制是数据库高可用的基石。现在,你的微服务系统已具备企业级数据保障能力!