一.安装docker compose
docker compose 多容器Docker应用的工具。通过Docker Compose,我们可以更方便地管理多个容器。安装命令如下:
bash
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
如果拉取失败,可能是网不通或者是网速太差,建议直接下载到本地,上传到服务器上。
离线安装(最稳,完全无网络依赖)
- 本地下载二进制文件:浏览器打开腾讯云镜像地址(1.29.2 x86_64):
https://mirrors.cloud.tencent.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64下载该文件(约 10MB,文件名改为docker-compose)。 - 上传并配置权限:
运行
# 上传后将文件放到指定目录(假设上传到/root/)
sudo mv /root/docker-compose /usr/local/bin/
# 赋予执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 建立软链接(适配系统PATH)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 验证
docker-compose --version

二、MySQL主从复制原理
MySQL主从复制是一种数据同步技术,主服务器(Master)将数据变更记录到二进制日志(Binlog)中,从服务器(Slave)读取这些日志并应用到自己的数据库中,从而实现数据的一致性。
2.1 主从复制流程
- 主服务器写入数据:主服务器接收到写操作后,将数据变更记录到二进制日志中。
- 从服务器拉取日志:从服务器连接到主服务器,并拉取二进制日志。
- 从服务器应用日志:从服务器将拉取到的二进制日志应用到自己的数据库中,完成数据同步。
三、使用Docker部署MySQL主从复制
3.1 创建Docker网络
为了方便容器之间的通信,我们首先创建一个Docker网络:
docker network create mysql-network
3.2 编写Docker Compose配置文件
创建一个名为docker-compose.yml的文件,内容如下:
bash
[root@k00 mysql-docker]# more docker-compose.yml
version: '3.8'
services:
master:
image: mysql:8.0
container_name: mysql-master
environment:
MYSQL_ROOT_PASSWORD: #你的主密码
MYSQL_DATABASE: mydb #主数据库名字
ports:
- "3306:3306"
networks:
- mysql-network
volumes:
- master-data:/var/lib/mysql
- ./master.cnf:/etc/mysql/conf.d/master.cnf
slave:
image: mysql:8.0
container_name: mysql-slave
environment:
MYSQL_ROOT_PASSWORD: #你的从库密码
MYSQL_DATABASE: mydb
ports:
- "3307:3306"
networks:
- mysql-network
volumes:
- slave-data:/var/lib/mysql
- ./slave.cnf:/etc/mysql/conf.d/slave.cnf
depends_on:
- master
networks:
mysql-network:
volumes:
master-data:
slave-data:
3.3 配置主服务器
创建一个名为master.cnf的文件,内容如下:
bash
[root@k00 mysql-docker]# more master.cnf
[mysqld]
log-bin=mysql-bin
server-id=1
binlog-do-db=mydb
3.4 配置从服务器
创建一个名为slave.cnf的文件,内容如下:
bash
[root@k00 mysql-docker]# more slave.cnf
[mysqld]
server-id=2
relay-log=mysql-relay-bin
log-bin=mysql-bin
binlog-do-db=mydb
3.5 启动集群
在docker-compose.yml文件所在的目录下执行以下命令启动集群:
docker-compose up -d
3.6 配置主从复制
进入主服务器容器:
docker exec -it mysql-master bash
登录MySQL:
mysql -uroot -prootpassword
创建一个用于复制的用户并授权:
bash
CREATE USER 'replicator'@'%' IDENTIFIED BY 'replicator用户的密码';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;
查看主服务器的状态:
SHOW MASTER STATUS;
记下File和Position的值,稍后会用到。
进入从服务器容器:
docker exec -it mysql-slave bash
登录MySQL:
mysql -uroot -prootpassword
配置从服务器:
记得按照上面show master status的值修改倒数一二行
bash
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='replicator',
MASTER_PASSWORD='replicator用户的密码',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=107;
启动从服务器:
START SLAVE;
检查从服务器状态:
bash
SHOW SLAVE STATUS\G
bash
[root@k00 ~]# docker exec -it mysql-slave bash
bash-5.1# mysql -uroot -pxxxxxxxxx
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 8.0.44 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: mysql-master
Master_User: replicator
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 157
Relay_Log_File: mysql-relay-bin.000006
Relay_Log_Pos: 373
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 157
Relay_Log_Space: 752
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 2cb3dc00-d3d7-11f。。。。。。。。
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
mysql>
如果Slave_IO_Running和Slave_SQL_Running都为Yes,则表示主从复制配置成功。
如果状态失败的话
报错1:
Last_IO_Error: Error connecting to source 'replicator@mysql-master:3306'. This was attempt 12/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
核心问题是从库 IO 线程无法连接主库 ,错误原因是 caching_sha2_password 认证插件要求安全连接(SSL),但当前复制未启用 SSL 导致认证失败。
MySQL 8.0+ 默认使用 caching_sha2_password 认证插件,该插件对非 SSL 连接有严格限制:
- 若用户密码是通过
caching_sha2_password加密,且未开启 SSL,会拒绝非 SSL 连接的认证; - 从库 IO 线程连接主库时未使用 SSL,触发此错误。
解决方案
为复制用户启用 "允许非 SSL 连接"(无需配置 SSL)
修改主库的复制用户,允许其在非 SSL 连接下使用 caching_sha2_password 认证:
-
登录主库 MySQL: mysql
mysql -u root -p -
修改复制用户(
replicator)的认证属性:mysql
-- 先更新用户密码(确保密码正确,同时允许非SSL) ALTER USER 'replicator'@'%' IDENTIFIED WITH caching_sha2_password BY '你的复制用户密码' REQUIRE NONE; -- 刷新权限 FLUSH PRIVILEGES;-
REQUIRE NONE:明确允许该用户不通过 SSL 连接; -
若主库是 MySQL 5.7(默认
mysql_native_password),可直接改为原生认证:mysql
ALTER USER 'replicator'@'%' IDENTIFIED WITH mysql_native_password BY '你的复制用户密码'; FLUSH PRIVILEGES;
-
报错2:
Last_IO_Errno: 13114 Last_IO_Error: Got fatal error 1236 from source when reading data from binary log: 'binlog truncated in the middle of event; consider out of disk space on source; the first event 'mysql-bin.000001' at 107, the last event read from './mysql-bin.000001' at 126, the last byte read from './mysql-bin.000001' at 180.'

file pos配置错了,重新填写

bash
SHOW MASTER STATUS;
-- 记录输出中的 File(如mysql-bin.000002)和 Position(如156)
情况 2:从库重新配置复制(核心操作)
sql
-- 1. 停止从库复制
STOP SLAVE;
-- 2. 重置从库的复制信息(清空旧的master info)
RESET SLAVE ALL; -- MySQL 8.0 用RESET SLAVE ALL,5.7用RESET SLAVE
-- 3. 重新指定主库信息(使用主库最新的File和Position)
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='replicator',
MASTER_PASSWORD='你的复制密码',
MASTER_LOG_FILE='主库SHOW MASTER STATUS返回的File', -- 如mysql-bin.000002
MASTER_LOG_POS=主库SHOW MASTER STATUS返回的Position; -- 如156
-- 4. 启动复制
START SLAVE;
-- 5. 检查复制状态
SHOW SLAVE STATUS\G
步骤 1:主库确认最新 binlog 位置(必做)
登录主库执行,记录输出的 File 和 Position:
sql
SHOW MASTER STATUS;
示例输出(你需以实际输出为准):
plaintext
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 1323 | | | |
+------------------+----------+--------------+------------------+-------------------+
步骤 2:从库彻底重置并重新配置复制
sql
-- 1. 停止从库复制(确保无残留连接)
STOP SLAVE;
-- 2. 重置从库所有复制信息(MySQL 8.0 必须加ALL)
RESET SLAVE ALL;
-- 3. 重新指定主库信息(替换为你主库的实际File和Position)
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='replicator',
MASTER_PASSWORD='你的复制密码', -- 确保密码正确
MASTER_LOG_FILE='mysql-bin.000003', -- 主库SHOW MASTER STATUS返回的File
MASTER_LOG_POS=1323; -- 主库SHOW MASTER STATUS返回的Position
-- 4. 启动复制
START SLAVE;
-- 5. 检查最终状态
SHOW SLAVE STATUS\G
3.7如果修改了docker compose
修改 docker-compose.yml 中数据库(MySQL)相关配置后,必须重启对应的容器才能让配置生效,具体操作分场景说明:
一、核心原则
Docker Compose 的配置仅在容器创建 / 重启 时生效,修改 docker-compose.yml 后,直接重启容器即可(无需重启 Docker 服务)。
二、具体操作步骤
场景 1:
仅修改 MySQL 容器的配置(如环境变量、端口、挂载卷等)
bash
运行
bash
# 1. 进入docker-compose.yml所在目录
cd /你的/docker-compose目录
# 2. 重启MySQL容器(推荐:先停再启,确保配置重载)
docker-compose stop mysql # 停止mysql容器(替换为你的服务名,如mysql-master/mysql-slave)
docker-compose up -d mysql # 后台启动mysql容器(-d 后台运行)
# 【简化命令】一步重启(等价于上面两步)
docker-compose restart mysql
# 查询服务名
[root@k00 mysql-docker]# docker-compose config --services
master
slave
[root@k00 mysql-docker]# docker-compose restart slave
Restarting mysql-slave ... done
场景 2:
新增 / 删除 MySQL 服务、修改网络 / 卷挂载等核心配置
如果修改了 services 结构、networks、volumes 等,仅 restart 可能不生效,需重新创建容器:
bash
运行
# 1. 停止并删除旧容器(数据卷不会被删除,放心执行)
docker-compose down mysql
# 2. 重新创建并启动容器(加载新配置)
docker-compose up -d mysql
3.8 常用容器操作命令(按服务名)
docker-compose.yml 中:
- 主库服务名:
master(容器名:mysql-master) - 从库服务名:
slave(容器名:mysql-slave)
1. 停止 / 启动 / 重启主库容器
bash
运行
# 停止主库
docker-compose stop master
# 启动主库(后台运行)
docker-compose up -d master
# 重启主库(一步到位)
docker-compose restart master
2. 停止 / 启动 / 重启从库容器
bash
运行
# 停止从库
docker-compose stop slave
# 启动从库(后台运行)
docker-compose up -d slave
# 重启从库(一步到位)
docker-compose restart slave
3. 重启所有服务(主 + 从)
bash
运行
docker-compose restart # 无需指定服务名,重启所有定义的服务
4.删除重建
- 停止单个服务(不删除容器):
bash
bash
docker-compose stop slave
- 停止并删除单个服务的容器:
bash
bash
docker-compose rm slave
# 或者强制删除
docker-compose rm -f slave
- 重新创建单个服务(停止、删除、重新创建):
bash
bash
docker-compose up -d --force-recreate slave
如果
场景1:只停止 slave 服务
bash
bash
docker-compose stop slave
场景2:停止 slave 并删除其容器
bash
bash
docker-compose stop slave
docker-compose rm slave
场景3:停止整个项目(包括 master 和 slave)
bash
bash
docker-compose down
3.9 数据库操作
sql
-- 创建数据库
CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 使用数据库
USE mydb;
-- 创建表
CREATE TABLE account (
id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
name VARCHAR(255) COMMENT '名称',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='账号表';

测试在主库创建account表,从库同步表成功