Docker 快速搭建 MySQL 5.7 主从复制环境
MySQL 的主从复制是实现数据备份、高可用、读写分离的关键技术之一。今天我们用 Docker 快速搭建一个 MySQL 5.7 主从复制环境,方便本地测试和学习。
环境准备
- 操作系统:CentOS / Ubuntu / WSL / Mac 均可
- Docker:已安装并启动
- MySQL 镜像:
mysql:5.7
# 拉取MySQL 5.7官方镜像
docker pull mysql:5.7
---
## 目录结构
```bash
/opt/
├── mysql_master/
│ ├── conf/ # 主库配置
│ ├── data/ # 主库数据挂载
│ └── log/ # 主库日志挂载
└── mysql_slave/
├── conf/ # 从库配置
├── data/ # 从库数据挂载
└── log/ # 从库日志挂载
创建目录并授权给 MySQL 容器使用:
mkdir -p /opt/mysql_master/{conf,data,log}
mkdir -p /opt/mysql_slave/{conf,data,log}
chown -R 999:999 /opt/mysql_*
配置文件(主从基本一致)
主库 /opt/mysql_master/conf/my.cnf
:
[client]
# 客户端默认使用的字符集
default-character-set=utf8
[mysql]
# mysql命令行客户端默认使用的字符集
default-character-set=utf8
[mysqld]
# 服务器启动时初始化连接,设置字符集校对规则
init_connect='SET collation_connection = utf8_unicode_ci'
# 服务器启动时初始化连接,设置字符集编码
init_connect='SET NAMES utf8'
# 服务器默认字符集
character-set-server=utf8
# 服务器默认字符集的排序规则
collation-server=utf8_unicode_ci
# 跳过客户端字符集协商,强制使用服务器设置的字符集
skip-character-set-client-handshake
# 禁用DNS反向解析,提升连接速度
skip-name-resolve
# MySQL服务器唯一标识ID,主从复制时必须不同
server_id=1
# 启用二进制日志功能,主库必须开启
log-bin=mysql-bin
# 只读模式,主库一般设为0,从库设为1
read-only=0
# 指定只对school数据库进行二进制日志记录(只记录school数据库的变更)
binlog-do-db=school
# 复制过滤,忽略以下数据库的复制(避免复制系统库)
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
从库 /opt/mysql_slave/conf/my.cnf
:
[client]
# 客户端默认使用的字符集
default-character-set=utf8
[mysql]
# mysql命令行客户端默认使用的字符集
default-character-set=utf8
[mysqld]
# 服务器启动时初始化连接,设置字符集校对规则
init_connect='SET collation_connection = utf8_unicode_ci'
# 服务器启动时初始化连接,设置字符集编码
init_connect='SET NAMES utf8'
# 服务器默认字符集
character-set-server=utf8
# 服务器默认字符集的排序规则
collation-server=utf8_unicode_ci
# 跳过客户端字符集协商,强制使用服务器设置的字符集
skip-character-set-client-handshake
# 禁用DNS反向解析,提升连接速度
skip-name-resolve
# 从库唯一的server_id,不能与主库相同
server_id=2
# 中继日志,用于记录从主库接收的二进制日志
relay-log=relay-log
# 从库也可以开启二进制日志,方便做多级复制或备份
log-bin=mysql-slave-bin
# 只读模式,从库一般设置为只读,防止误操作写入数据
read-only=1
# 复制过滤,忽略系统库,避免复制系统数据库内容
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
启动主库容器
docker run -p 3306:3306 \
--name mysql_master \
-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=root \
-d mysql:5.7
主库配置
进入主库容器:
docker exec -it mysql_master bash
mysql -uroot -proot
执行 SQL:
CREATE USER 'backup'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'backup'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
记住 File
和 Position
(如 mysql-bin.000001
, 154
)
启动从库容器
docker run -p 3307:3306 \
--name mysql_slave \
-v /opt/mysql_slave/log:/var/log/mysql \
-v /opt/mysql_slave/data:/var/lib/mysql \
-v /opt/mysql_slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
--link mysql_master:mysql_master \
-d mysql:5.7
--link
会在容器内创建主库的别名mysql_master
,用于网络通信
配置从库复制
连接从库:
mysql -h 127.0.0.1 -P 3307 -uroot -proot
执行复制配置 SQL:
CHANGE MASTER TO
MASTER_HOST='mysql_master',
MASTER_USER='backup',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154,
MASTER_PORT=3306;
START SLAVE;
SHOW SLAVE STATUS\G
确认两个关键字段是 Yes
:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
清算效果
在主库执行:
CREATE DATABASE school;
USE school;
CREATE TABLE test (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO test VALUES (1, 'hello slave');
然后在从库查看是否同步:
USE school;
SELECT * FROM test;
如果能查到,说明主从配置成功!
常见问题排查
问题 | 原因 | 解决方法 |
---|---|---|
容器启动秒退 | 数据卷权限或配置错误 | 检查挂载目录权限是否 999:999 ,my.cnf 配置是否正确 |
CHANGE MASTER TO 报警 | 参数空格或逗号问题 | 精确检查 SQL 是否多了空格或打错了关键词 |
Slave_IO_Running 或 Slave_SQL_Running 为 No | 主从连接或配置不通 | 看日志 SHOW SLAVE STATUS\G 最底部 Last_IO_Error / Last_SQL_Error |
小结
你现在已经学会:
- 使用 Docker 构建 MySQL 主从环境
- 掌握基本主从配置参数
- 成功实现主从数据同步
这是后续实现读写分离、负载均衡、灾处备份的基石。
如果这篇文章对你有帮助,欢迎点一下赞或收藏!