Docker 安装mysql8.0 主从同步

一.安装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. 本地下载二进制文件:浏览器打开腾讯云镜像地址(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)。
  2. 上传并配置权限:

运行

复制代码
# 上传后将文件放到指定目录(假设上传到/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 主从复制流程

  1. 主服务器写入数据:主服务器接收到写操作后,将数据变更记录到二进制日志中。
  2. 从服务器拉取日志:从服务器连接到主服务器,并拉取二进制日志。
  3. 从服务器应用日志:从服务器将拉取到的二进制日志应用到自己的数据库中,完成数据同步。

三、使用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;

记下FilePosition的值,稍后会用到。

进入从服务器容器:

复制代码
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_RunningSlave_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 认证:

  1. 登录主库 MySQL: mysql

    复制代码
    mysql -u root -p
  2. 修改复制用户(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 结构、networksvolumes 等,仅 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.删除重建
  1. 停止单个服务(不删除容器):

bash

bash 复制代码
docker-compose stop slave
  1. 停止并删除单个服务的容器:

bash

bash 复制代码
docker-compose rm slave
# 或者强制删除
docker-compose rm -f slave
  1. 重新创建单个服务(停止、删除、重新创建):

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表,从库同步表成功

相关推荐
AI算法蒋同学2 小时前
5 个用于人工智能基础设施的 Docker 容器
人工智能·docker·容器
不会kao代码的小王2 小时前
openEuler容器化实战:用Docker和iSulad部署Redis
redis·docker·容器
BUG_MeDe2 小时前
Linux 下VRF的简单应用
linux·运维·服务器
babytiger2 小时前
用python在服务器上开个可以输入帐号密码的代理服务器
运维·服务器
向山行_wolf2 小时前
ubuntu22.04鼠标速度配置
运维·服务器
暮光6292 小时前
Ubuntu 20.04 文件管理器图标卡死
linux·运维·ubuntu
java_logo3 小时前
RUSTFS Docker 容器化部署指南
java·运维·docker·容器·jenkins·运维开发
布列瑟农的星空3 小时前
Nginx https证书配置
运维
Wang's Blog3 小时前
Elastic Stack梳理:Logstash 高级数据处理与监控运维实战指南
运维·搜索引擎·elastic search