当前位置: 首页 > news >正文

11、Docker Compose 配置Mysql主从(单虚拟机)

🚀 Docker Compose 配置一主两从的 MySQL 主从复制集群(含详解与实战)

标签:Docker | MySQL | 主从复制 | Compose | 分布式 | 架构搭建
难度:🌟🌟🌟 中等
适用人群:后端开发、架构师、运维工程师


📚 目录导航

  • 一、前言
  • 二、MySQL 主从复制原理简述
  • 三、项目目录结构
  • 四、docker-compose.yml 配置详解
  • 五、my.cnf 主从配置文件
  • 六、初始化 SQL 创建复制用户
  • 七、启动服务与配置主从复制
  • 八、主从复制验证
  • 九、常见问题排查
  • 十、总结

一、前言

在高并发环境下,为了解决 MySQL 单点瓶颈,常见的做法是配置主从复制,实现读写分离,提高系统性能与可用性。本文通过 Docker Compose 一键搭建 一主两从 的 MySQL 主从集群,并手动配置复制关系,适合本地开发和测试环境快速模拟分布式数据库结构。


二、MySQL 主从复制原理简述

MySQL 主从复制是一种异步复制机制:

  1. 主库将数据更改写入 二进制日志(binlog)
  2. 从库通过 IO 线程 拉取主库的 binlog
  3. 从库的 SQL 线程 将 binlog 应用到本地数据库

主从结构:

+---------+         +---------+         +---------+
|  Master |  --->   |  Slave1 |  --->   |  Slave2 |
+---------+         +---------+         +---------+
写操作              读操作               读操作

三、项目目录结构


mysql-replication/
├── docker-compose.yml
├── master/
│   └── my.cnf
│   └── init.sql
├── slave1/
│   └── my.cnf
├── slave2/
│   └── my.cnf

四、docker-compose.yml 配置详解

version: '3.9'services:master:image: mysql:8.0container_name: mysql-masterrestart: alwaysports:- "3307:3306"environment:MYSQL_ROOT_PASSWORD: rootvolumes:- ./master/my.cnf:/etc/mysql/my.cnf- ./master/init.sql:/docker-entrypoint-initdb.d/init.sqlnetworks:- mysql-clusterslave1:image: mysql:8.0container_name: mysql-slave1restart: alwaysports:- "3308:3306"environment:MYSQL_ROOT_PASSWORD: rootvolumes:- ./slave1/my.cnf:/etc/mysql/my.cnfnetworks:- mysql-clusterdepends_on:- masterslave2:image: mysql:8.0container_name: mysql-slave2restart: alwaysports:- "3309:3306"environment:MYSQL_ROOT_PASSWORD: rootvolumes:- ./slave2/my.cnf:/etc/mysql/my.cnfnetworks:- mysql-clusterdepends_on:- masternetworks:mysql-cluster:driver: bridge

📌 配置项详解

配置项说明
versionCompose 文件格式版本
services定义每个服务(容器)
image使用的 MySQL 镜像版本
container_name自定义容器名称,便于主从识别
restart容器异常自动重启
ports映射到主机端口
environment设置环境变量(如 root 密码)
volumes挂载本地配置或初始化 SQL 脚本
depends_on声明依赖启动顺序
networks配置服务所属网络,实现容器互通

五、my.cnf 主从配置文件

master/my.cnf

[mysqld]
server-id=1                          # 唯一标识主库,不能与从库重复
log-bin=mysql-bin                    # 启用二进制日志,用于复制
binlog-format=ROW                    # 使用行级复制格式,精确且安全
gtid_mode=ON                        # 开启 GTID 复制模式,简化复制管理
enforce_gtid_consistency=ON         # 确保 GTID 复制的一致性
log_slave_updates=ON                # 允许从库写日志,支持多级复制

slave1/my.cnf

[mysqld]
server-id=2                        # 唯一标识,从库1
relay-log=relay-bin               # 中继日志文件
read_only=ON                      # 从库只读,避免写操作
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON

slave2/my.cnf

[mysqld]
server-id=3                        # 唯一标识,从库2
relay-log=relay-bin
read_only=ON
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON

六、初始化 SQL 创建复制用户(master/init.sql)

CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'replpass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

这三条 SQL 命令是用于设置 MySQL 主从复制(Replication)所需的账号权限的,逐条解释如下:


✅ 第一句:

CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'replpass';

意思是:

  • 创建一个名为 repl 的用户。
  • @'%' 表示该用户可以从任何主机连接(即 slave 容器连接 master)。
  • 使用 mysql_native_password 插件进行身份验证(兼容性最好,尤其在 MySQL 8 中设置复制用户建议指定)。
  • 密码是 'replpass'

🧠 补充说明
MySQL 8.0 开始默认的密码插件是 caching_sha2_password,但它在某些客户端连接或复制场景下可能不兼容,因此常推荐显式指定 mysql_native_password


✅ 第二句:

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

这句是给刚创建的用户 repl 授予 复制权限

  • REPLICATION SLAVE 是允许该用户执行 CHANGE MASTER TOSTART SLAVE 等操作。
  • ON *.* 表示作用于所有数据库。

✅ 第三句:

FLUSH PRIVILEGES;

意思是让权限修改 立即生效(在 MySQL 中大多数情况下并非必须,但是一种安全的做法)。


📦 总结一下这三行是干嘛的?

这是在主库(mysql-master)中创建一个能被从库(mysql-slave)连接的专用账号 repl,并授予它复制权限。

从库使用这个账号去主库“同步 binlog 事件”,完成数据复制。


👇 你后续会在从库执行如下命令使用这个账号:

CHANGE MASTER TOMASTER_HOST='mysql-master',MASTER_USER='repl',MASTER_PASSWORD='replpass',MASTER_LOG_FILE='xxx',MASTER_LOG_POS=xxx;

七、启动服务与配置主从复制

1️⃣ 启动集群

docker compose up -d

2️⃣ 查看 master 的 binary log 位置

docker exec -it mysql-master mysql -uroot -proot -e "SHOW MASTER STATUS\G"

在这里插入图片描述

得到 FilePosition 信息,例如:mysql-bin.000003, Position: 197

3️⃣ 分别配置 slave1 和 slave2 复制主库

CHANGE MASTER TOMASTER_HOST='mysql-master',MASTER_USER='repl',MASTER_PASSWORD='replpass',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=197;START SLAVE;

执行方式(示例 slave1):

docker exec -it mysql-slave1 mysql -uroot -proot -e "CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='repl', MASTER_PASSWORD='replpass', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=197; START SLAVE;"

执行方式(示例 slave2):

docker exec -it mysql-slave2 mysql -uroot -proot -e "CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='repl', MASTER_PASSWORD='replpass', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=197; START SLAVE;"

如果是在三台虚拟机之间配置 MySQL 主从,只需要在从库上将 MASTER_HOST 设置为 主库所在虚拟机的 IP 地址 即可完成跨虚拟机的主从复制配置。三台虚拟机需要 能互相 ping 通、端口开放(通常是 3306)。

🔍 详细说明:

配置项说明
MASTER_HOST主库的 真实 IP 地址,不能写 localhost 或容器名,除非是同一个网络。
MASTER_USER主库中授权用于复制的账号,权限通常为 REPLICATION SLAVE
MASTER_PASSWORD对应账号的密码。
MASTER_LOG_FILE主库当前二进制日志文件名(通过 SHOW MASTER STATUS; 获取)。
MASTER_LOG_POS当前日志的偏移量位置。

八、主从复制验证

mysql-master 中插入数据:

CREATE DATABASE testdb;
USE testdb;
CREATE TABLE user (id INT PRIMARY KEY, name VARCHAR(50));
INSERT INTO user VALUES (1, 'Tom');

然后在 slave1、slave2 查询:

SELECT * FROM testdb.user;

输出一致即说明主从同步成功。

在这里插入图片描述


九、常见问题排查

问题解决方案
getaddrinfo for mysql-master failed检查 container_name 是否设置为 mysql-master
Slave_IO_Running: No检查 MASTER_LOG_FILE 和 POS 是否正确
Access denied for user 'repl'检查 repl 用户权限,是否使用了 mysql_native_password

十、总结

本文完整介绍了如何通过 Docker Compose 一键构建一主两从的 MySQL 主从复制集群,支持读写分离与高可用架构演练。你可以在此基础上扩展:

  • 增加 MySQL Router 或 ProxySQL 实现自动读写分离
  • 接入 Spring Boot 实现主从读写动态切换
  • 增加备份 + 监控模块(如 Prometheus + Grafana)

📌 点赞 + 收藏 + 关注不迷路!

http://www.dtcms.com/a/302857.html

相关文章:

  • 树状数组的概念、结构及实现
  • 塔能科技物联运维平台及城市照明市场竞争力分析
  • 国产测试用例管理工具横向评测:DevOps时代如何选择最适合的协作平台?
  • window显示驱动开发—RecycleCreateCommandList
  • Angular 依赖注入
  • 网络 编程
  • 洛谷刷题7.28
  • 基于AFLFast的fuzz自动化漏洞挖掘(1)
  • 【HTTP】防XSS+SQL注入:自定义HttpMessageConverter过滤链深度解决方案
  • 【React Context API 优化与性能实践指南】
  • DBAPI 实现分页查询的两种方法
  • 阿里云Ubuntu 22.04 ssh隔一段时间自动断开的解决方法
  • 【力扣热题100】哈希——两数之和
  • 【mysql】—— mysql中的timestamp 和 datetime(6) 有什么区别,为什么有的地方不建议使用timestamp
  • 智能制造,从工厂建模,工艺建模,柔性制造,精益制造,生产管控,库存,质量等多方面讲述智能制造的落地方案。
  • 破解PCB制造痛点,盘古信息IMS MOM 铸就数字化标杆工厂
  • PL/SQL
  • 开疆智能ModbusRTU转Profinet网关连接西门子CP341配置案例
  • DDD之整体设计流程(2)
  • debian系统分卷是不会影响系统启动速度?
  • 排序算法 (Sorting Algorithms)-Python示例
  • Android 系统架构
  • 阿里云 API 网关 x OKG:游戏连接治理的「最后一公里」
  • 阿里云正式开源 LoongSuite:打造 AI 时代的高性能低成本可观测采集套件
  • 电脑不小心误删了文件怎么恢复??
  • AI资讯日报 - 2025年07月28日
  • EXCEL批量生成超链接引用无效的情况
  • Kotlin中Flow
  • 基于Spring Boot的装饰工程管理系统(源码+论文)
  • 一个典型的微控制器MCU包含哪些模块?