基于 Docker + Docker Compose
使用 GTID 自动定位(更可靠)
日志挂载到宿主机并自动保留 60 天
仅用于 开发/测试 ,不可用于生产
docker安装可参照 day02 -- docker
第一步:创建项目目录
bash
# 创建并进入项目目录
mkdir -p /opt/mysql-replication && cd /opt/mysql-replication
# 创建所需子目录
mkdir -p \
data/{master,slave} \
logs/{master,slave} \
init \
conf
第二步:创建配置文件
1. 主库配置 conf/master.cnf
bash
cat > conf/master.cnf << 'EOF'
[mysqld]
server-id=1
log-bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
# 日志设置
log_error = /var/log/mysql/error.log
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
general_log = OFF
EOF

2. 从库配置 conf/slave.cnf
bash
cat > conf/slave.cnf << 'EOF'
[mysqld]
server-id=2
gtid_mode=ON
enforce_gtid_consistency=ON
read_only=ON
# 日志设置
log_error = /var/log/mysql/error.log
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
general_log = OFF
EOF
第三步:创建初始化 SQL 脚本
1. 主库初始化脚本 init/master.sql
bash
cat > init/master.sql << 'EOF'
-- 创建复制专用用户(兼容 MySQL 8.0 客户端)
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'slavepass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
EOF

2. 从库初始化脚本 init/slave.sql
bash
cat > init/slave.sql << 'EOF'
-- 安全停止旧复制(首次无影响)
STOP SLAVE;
-- 配置主从连接(使用 Docker 服务名)
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='repl',
MASTER_PASSWORD='slavepass',
MASTER_AUTO_POSITION=1;
-- 启动复制
START SLAVE;
-- 提示信息(日志可见)
SELECT 'Slave replication started.' AS Info;
EOF
第四步:创建 docker-compose.yml
bash
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
mysql-master:
image: mysql:8.0
container_name: mysql-master
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- ./data/master:/var/lib/mysql
- ./init/master.sql:/docker-entrypoint-initdb.d/master.sql
- ./conf/master.cnf:/etc/mysql/conf.d/master.cnf
- ./logs/master:/var/log/mysql
ports:
- "33060:3306"
networks:
- mysql-net
mysql-slave:
image: mysql:8.0
container_name: mysql-slave
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- ./data/slave:/var/lib/mysql
- ./init/slave.sql:/docker-entrypoint-initdb.d/slave.sql
- ./conf/slave.cnf:/etc/mysql/conf.d/slave.cnf
- ./logs/slave:/var/log/mysql
ports:
- "33070:3306"
depends_on:
- mysql-master
networks:
- mysql-net
networks:
mysql-net:
driver: bridge
EOF
第五步:启动服务
bash
# 启动容器(后台运行)
docker compose up -d
# 查看启动状态
docker compose ps
首次启动需 20~30 秒,请耐心等待 MySQL 初始化完成。

第六步:验证主从复制是否成功
1. 检查从库复制状态
bash
docker exec -i mysql-slave mysql -uroot -prootpass -e "SHOW SLAVE STATUS\G" \
| grep -E "Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master|Master_Host"
正常输出应包含:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
Master_Host: mysql-master
2. 手动测试数据同步
bash
# 在主库创建测试数据
docker exec -i mysql-master mysql -uroot -prootpass -e "
CREATE DATABASE IF NOT EXISTS test_replication;
USE test_replication;
CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50));
INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob');
"
# 在从库查询
docker exec -i mysql-slave mysql -uroot -prootpass -e "
SELECT * FROM test_replication.users;
"
应返回两条记录,说明同步成功!

上图中的警告是在命令行中直接使用了 -prootpass,这会导致密码可能被其他系统用户通过 ps 命令查看到,或者记录在 shell 历史中(密码泄露风险)。
第七步:配置日志自动清理(最多保留 60 天)
利用宿主机
logrotate实现日志轮转与清理。
1. 获取当前项目绝对路径
bash
PROJECT_PATH=$(pwd)
echo "项目路径: $PROJECT_PATH"
2. 创建 logrotate 配置文件
bash
sudo tee /etc/logrotate.d/mysql-replication > /dev/null << EOF
${PROJECT_PATH}/logs/master/*.log
${PROJECT_PATH}/logs/slave/*.log
{
daily
missingok
rotate 60
compress
delaycompress
notifempty
copytruncate
}
EOF
3. 验证配置(可选)
bash
# 测试语法
sudo logrotate -d /etc/logrotate.d/mysql-replication
# 强制立即轮转一次(调试用)
sudo logrotate -f /etc/logrotate.d/mysql-replication
轮转后会在
logs/*/目录生成.1、.1.gz等归档文件系统每天自动运行,超过 60 天的日志将被自动删除

第八步:开发环境重置(谨慎操作!)
仅限本地开发!会清空所有数据和日志!
bash
# 1. 停止并删除容器
docker compose down
# 2. 清空数据和日志
rm -rf data/master/* data/slave/* logs/master/* logs/slave/*
# 3. 重新启动
docker compose up -d

远程连接数据库需要安全组/防火墙开放33060,33070端口,用户名与密码如下:
| 用户名 | 密码 | 备注 |
|---|---|---|
| root | rootpass | 主从库root用户 |
| repl | slavepass | 从库复制主库的专用账号,此账号不能登录从库 |
第九步:常用操作命令速查
| 操作 | 命令 |
|---|---|
| 查看主库错误日志 | tail -f logs/master/error.log |
| 查看从库慢查询 | tail -f logs/slave/slow.log |
| 进入主库 CLI | docker exec -it mysql-master mysql -uroot -prootpass |
| 进入从库 CLI | docker exec -it mysql-slave mysql -uroot -prootpass |
| 重启服务 | docker-compose restart |
| 查看容器日志 | docker logs mysql-slave |
注意事项
- 不要在生产环境使用
rm -rf data/!生产环境应使用RESET SLAVE ALL+ 备份恢复。 - 若从库无法连接主库,请检查:
MASTER_HOST是否为mysql-master(Docker 服务名)- 主库是否已创建
repl用户且密码正确 - 主从
gtid_mode配置是否一致
- 日志挂载依赖
logrotate,确保系统已安装(Ubuntu/Debian 默认已装)