【DOCKER容器实战】-2MySQL

文章目录

  • 容器化应用实战:MySQL
    • 一、单节点部署
      • [1. 启动 MySQL 容器](#1. 启动 MySQL 容器)
      • [2. 容器内客户端直接访问](#2. 容器内客户端直接访问)
      • [3. 宿主机客户端访问](#3. 宿主机客户端访问)
    • 二、主从复制集群部署
      • [1. 主节点部署](#1. 主节点部署)
      • [2. 主节点配置(my.cnf)](#2. 主节点配置(my.cnf))
      • [3. 从节点部署](#3. 从节点部署)
      • [4. 使用自定义网络替代 `--link`](#4. 使用自定义网络替代 --link)
        • [① `--link` 有什么缺点(为什么淘汰)](#① --link 有什么缺点(为什么淘汰))
        • [② 自定义网络能干什么](#② 自定义网络能干什么)
        • [③ MySQL 主从完整实操替换(替换 `--link`)](#③ MySQL 主从完整实操替换(替换 --link))
        • [④ 常用网络命令](#④ 常用网络命令)
        • [⑤ 三种 docker 网络简单对比](#⑤ 三种 docker 网络简单对比)
        • [⑥ 主从复制里的 DNS 小重点](#⑥ 主从复制里的 DNS 小重点)
      • [5. 从节点配置(my.cnf)](#5. 从节点配置(my.cnf))
      • [6. 主库创建复制账号](#6. 主库创建复制账号)
      • [7. 查看主库 binlog 状态](#7. 查看主库 binlog 状态)
      • [8. 从库配置并启动复制](#8. 从库配置并启动复制)
    • 三、常见报错排查
      • [1. ERROR 1794:server-id 未配置或未生效](#1. ERROR 1794:server-id 未配置或未生效)
      • [2. ERROR 3021:IO 线程运行中修改主从配置](#2. ERROR 3021:IO 线程运行中修改主从配置)
    • 四、命令速查

容器化应用实战:MySQL

!note 核心摘要

  • 数据持久化 :挂载 /var/lib/mysql 数据目录,容器删除后数据仍保留在宿主机
  • 主从复制 :主库开启 binlog + 创建复制账号,从库 change master to + start slaveSlave_IO_RunningSlave_SQL_Running 均为 Yes 即成功
  • 容器互联--link 已过时,改用自定义网络,容器名直接当域名用
  • 高频报错 :ERROR 1794 是 server-id 未配置/未生效;ERROR 3021 是未先 stop slave 就执行 change master to
    官方参考:Hardened Images catalog | MySQL | Guides | Docker Hub

一、单节点部署

1. 启动 MySQL 容器

bash 复制代码
[root@localhost ~]# docker run -p 3306:3306 \
> --name mysql_01 \
> -v /opt/mysql/log:/var/log/mysql \
> -v /opt/mysql/data:/var/lib/mysql \
> -v /opt/mysql/conf:/etc/mysql/conf.d \
> -e MYSQL_ROOT_PASSWORD=root \
> -d \
> mysql:5.7
4513fdf2d6a9bb95e2d9b80319149abf15ecd362a25702d4698a03c8a0a9bd50

单行写法:

bash 复制代码
[root@localhost ~]# docker run -d -p 3306:3306 --name mysql -v /opt/mysql/log:/var/log/mysql -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root mysql:5.7
ebd20c54e8d4d3f43c609aa0caaab99f717b0ce765892f81d64763847d603380
bash 复制代码
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED        STATUS        PORTS                                         NAMES
ebd20c54e8d4   mysql:5.7  "docker-entrypoint.s..."   4 seconds ago  Up 4 seconds  0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql

参数解析

  1. -p 3306:3306:端口映射,宿主机 3306 映射容器 mysql 3306 端口
  2. --name mysql:给容器设置名字
  3. -v 数据卷挂载三处:
    • /opt/mysql/log:/var/log/mysql:日志目录挂载
    • /opt/mysql/data:/var/lib/mysql数据库数据目录挂载(最重要,持久化数据)
    • /opt/mysql/conf:/etc/mysql/conf.d:自定义配置文件挂载
  4. -e MYSQL_ROOT_PASSWORD=root:环境变量,设置 root 用户密码为 root
  5. -d:后台守护模式运行
  6. mysql:5.7:使用 mysql 5.7 镜像

!note 数据持久化

33060 是 mysql 5.7 默认 X-Protocol 端口。数据挂载到宿主机,就算容器删除,数据库数据还保存在宿主机 /opt/mysql/data,实现数据持久化。

批量停止删除容器:

bash 复制代码
# 停止所有容器
docker stop $(docker ps -aq)
# 删除所有容器
docker rm $(docker ps -aq)

2. 容器内客户端直接访问

bash 复制代码
[root@localhost ~]# docker exec -it mysql mysql -uroot -proot
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 2
Server version: 5.7.44 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.
...
mysql>

参数说明

  1. docker exec -it mysql
    • -i:保持标准输入打开
    • -t:分配伪终端
    • mysql:容器名称
  2. 后面的 mysql -uroot -proot容器内部执行 mysql 客户端命令
    • -uroot:用户名 root
    • -proot:密码 root

!warning 密码安全

直接在命令行写密码不安全,会留下历史记录。

更安全的登录方式(不把密码写在命令行)

bash 复制代码
docker exec -it mysql mysql -uroot -p

执行后交互式输入密码,不会泄露密码到命令历史。

!\[03_云原生/Docker/image/7d0471b09959ff74432b2dcae1355cb4_MD5.jpg]

3. 宿主机客户端访问

先在宿主机安装 mariadb 客户端(协议兼容,可连接 MySQL):

bash 复制代码
[root@localhost ~]# yum install mariadb -y
bash 复制代码
[root@localhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.44 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |

参数解释

  1. yum install mariadb -y:宿主机安装 mariadb 客户端,用来连接 docker 里的 mysql 服务
  2. mysql 连接参数
    • -h 192.168.100.152:数据库服务 IP(宿主机 IP)
    • -P 3306:端口,大写 P,宿主机映射端口
    • -uroot:用户名 root
    • -proot:密码 root

!warning 连接地址注意

虽然用的是 mariadb 客户端,但是可以正常连接 MySQL 5.7 服务,协议兼容。

-h 指定宿主机 IP,不要写 127.0.0.1127.0.0.1 是容器内部回环地址。

二、主从复制集群部署

1. 主节点部署

bash 复制代码
[root@localhost ~]# 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
4ffff00b1ec30ecc25fa32a5260101dd757b11416fbb451807784535ccd4ca0d
bash 复制代码
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND                  CREATED        STATUS        PORTS                                         NAMES
f28374fcd5a4   mysql:5.7  "docker-entrypoint.s..."   5 seconds ago  Up 5 seconds  0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql_master

验证登录:

bash 复制代码
[root@localhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

参数说明

  1. --name mysql_master:容器命名为主节点 mysql_master
  2. 挂载目录全部带上 mysql_master 区分主节点数据,避免和从节点目录冲突
    • /opt/mysql_master/log:主节点日志
    • /opt/mysql_master/data:主节点数据文件
    • /opt/mysql_master/conf:主节点配置文件
  3. -p 3306:3306:主节点映射宿主机 3306 端口
  4. 环境变量 MYSQL_ROOT_PASSWORD=root 设置 root 密码
  5. 登录使用宿主机 IP 192.168.100.152,端口 3306 验证连通性。

2. 主节点配置(my.cnf)

bash 复制代码
[root@localhost ~]# vim /opt/mysql_master/conf/my.cnf
ini 复制代码
[client]
default-character-set=utf8

[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
skip-name-resolve

server_id=1
log-bin=mysql-bin
read-only=0
binlog-do-db=school

replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

核心主从配置项说明

  1. server_id=1:数据库节点 ID,主库设置为 1,从库必须是别的数字,集群内不能重复
  2. log-bin=mysql-bin:开启二进制日志,文件名前缀 mysql-bin,主从复制依赖 binlog
  3. read-only=0:主库关闭只读,可以读写
  4. binlog-do-db=school:只把 school 库的变更记录进 binlog,只同步这个库
  5. replicate-ignore-db:忽略同步的库,mysqlsysinformation_schemaperformance_schema 系统库不同步
  6. skip-name-resolve:跳过域名解析,加快数据库连接速度
  7. 上面一大部分是 utf8 字符集相关配置,统一数据库字符集

修改完配置后需要重启 mysql_master 容器生效:

bash 复制代码
docker restart mysql_master

3. 从节点部署

bash 复制代码
[root@localhost ~]# 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 \
> -d \
> --link mysql_master:mysql_master \
> mysql:5.7
5c1ebfd265d0b8ec706408bf2681d82d5039f78cb33fe292234c888a3f8f3d50
bash 复制代码
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
5c1ebfd265d0   mysql:5.7  "docker-entrypoint.s..."   31 seconds ago  Up 30 seconds  33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql_slave
f28374fcd5a4   mysql:5.7  "docker-entrypoint.s..."   10 hours ago    Up 10 hours    0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql_master

参数说明

  1. -p 3307:3306:从库宿主机端口使用 3307,容器内部依然 3306,和主库端口区分开
  2. --name mysql_slave:容器命名为从节点
  3. 挂载目录全部为 mysql_slave,与主库目录隔离,防止数据冲突
  4. --link mysql_master:mysql_master:旧版 docker 容器互联,在 slave 容器内可以用主机名 mysql_master 访问主库容器
  5. root 密码同样设置为 root

!warning --link 已过时

--link 属于过时技术,新版本推荐使用 docker 自定义网络,见下节。

--link老旧的容器互联方案 ,已经不推荐继续使用;自定义网络(custom bridge) 是 docker 官方推荐的替代方案,用来解决容器之间互相通信。

  1. 只能单向:A link B,A 能访问 B,B 不能访问 A
  2. 配置写死在容器启动参数,容器重启后域名解析偶发失效
  3. 只支持桥接默认 bridge 网络
  4. 不支持多容器集群,做主从、集群很不方便
② 自定义网络能干什么
  • 创建一个独立网桥,加入这个网络的所有容器互相可以通过容器名字直接通信
  • 双向互通,不需要 link
  • DNS 自动解析:容器名直接当作主机名
  • 网络隔离:不在这个网络的容器访问不到
  • 容器后期可以随时加入/退出网络,不用重建容器
③ MySQL 主从完整实操替换(替换 --link

创建自定义网络:

bash 复制代码
# 创建名为 mysql-net 的自定义桥接网络
docker network create mysql-net

启动主节点,加入自定义网络(去掉 --link):

bash 复制代码
docker run -p 3306:3306 \
--name mysql_master \
--network mysql-net \
-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

启动从节点,同样加入同一个网络,删掉 --link

bash 复制代码
docker run -p 3307:3306 \
--name mysql_slave \
--network mysql-net \
-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 \
-d mysql:5.7

!note 效果

此时在 mysql_slave 容器内部,直接写主机名 mysql_master 就能访问主库,效果和 link 一样,但是更稳定。配置主从复制时 master_host 就填 mysql_master

④ 常用网络命令
bash 复制代码
# 查看所有网络
docker network ls

# 查看网络详情,看哪些容器挂载进来
docker network inspect mysql-net

# 将已有容器追加加入网络(容器已经启动也可以加)
docker network connect mysql-net 容器名

# 容器脱离网络
docker network disconnect mysql-net 容器名

# 删除网络(没有容器挂载才能删)
docker network rm mysql-net
⑤ 三种 docker 网络简单对比
网络类型 用途
bridge(默认) 默认网桥,容器之间默认不通,需要 link,老旧
自定义 bridge 开发/测试用,适合 MySQL 主从这种多容器集群,推荐
host 容器直接复用宿主机网络,不做端口映射,性能高
⑥ 主从复制里的 DNS 小重点

在从库执行 change master to

sql 复制代码
CHANGE MASTER TO
MASTER_HOST='mysql_master',   # 自定义网络直接写容器名字!DNS 自动解析
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;

MASTER_HOST 直接填容器名字,不需要写 IP,自定义网络 DNS 自动解析。

!tip 总结

以后做容器集群,不要再写 --link,直接新建自定义网络,所有容器 --network xxx 加入同一个网络即可。主库、从库两个容器都必须加入同一个自定义网络。

原理:自定义网络只有处在这个网络里面的容器,才可以用容器名字互相 DNS 解析通信。

  • 只有从库进去、主库没进:mysql_slave 解析不到 mysql_master,主从复制连不上。
  • 两个都加入同一个 mysql-net:slave 内部写主机名 mysql_master 就能找到主库。

两种情况处理

情况 1:还没启动容器(全新部署,推荐)

  • 创建网络:docker network create mysql-net
  • 主库启动参数加上 --network mysql-net
  • 从库启动参数加上 --network mysql-net
  • 直接删掉旧的 --link 参数,不再使用

情况 2:主库 mysql_master 已经跑起来了(容器已存在)

不用删掉重建主库,直接把运行中的容器追加接入网络:

bash 复制代码
# 将已运行的主库加入自定义网络
docker network connect mysql-net mysql_master

# 再把从库也接进来,如果从库也已经启动
docker network connect mysql-net mysql_slave

验证是否加入成功:

bash 复制代码
docker network inspect mysql-net

看输出里的 Containers 节点,要同时出现 mysql_mastermysql_slave 两个容器。

测试连通性------进入从库容器内部测试能否解析主库名字:

bash 复制代码
docker exec -it mysql_slave ping mysql_master

能 ping 通,代表网络没问题,后面配置主从复制时 MASTER_HOST='mysql_master' 就可以生效。

!note 小提醒

  • 宿主机访问数据库不受自定义网络影响:宿主机依旧访问 192.168.100.152:3306(主)、192.168.100.152:3307(从),端口映射依旧生效。
  • 自定义网络只管容器与容器之间互通,不影响宿主机访问容器。

5. 从节点配置(my.cnf)

bash 复制代码
[root@localhost ~]# vim /opt/mysql_slave/conf/my.cnf
ini 复制代码
[client]
default-character-set=utf8

[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
skip-name-resolve

server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=school

replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

和主库配置关键差异

  1. server_id=2必须和主库不一样,主库是 1,从库设置 2,集群所有节点 id 不能重复
  2. read-only=1:从库开启只读,普通用户不能写入(super 权限账号依旧可以写)
  3. 字符集、binlog-do-db、忽略同步库的配置和主库保持一致

修改配置后重启从库容器生效:

bash 复制代码
docker restart mysql_slave

!note 补充知识点

  • 从库开启 log-bin,代表开启从库二进制日志,用于链式主从(A→B→C,B 既是从库又是下一级的主库);普通一主一从场景从库也可以不开 binlog。
  • read-only=1 不会限制 root 超级账号写入,生产从库日常不要用 root 操作。

6. 主库创建复制账号

bash 复制代码
[root@localhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306
sql 复制代码
MySQL [(none)]> grant replication slave on *.* to 'backup'@'%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.02 sec)

MySQL [(none)]> flush privileges;
Query OK, 0 rows affected (0.01 sec)

语句解释

  1. grant replication slave on *.* to 'backup'@'%' identified by '123456'; 创建主从复制专用账号 backup,密码 123456@'%' 代表允许从任意地址连接,只授予 replication slave 复制权限,不授予业务增删改查权限

!note MySQL 5.7 会报 1 个 warning,是密码策略提示,不影响功能。

  1. flush privileges;:刷新权限,让新建账号立刻生效。
  2. docker restart mysql_master:重启主库容器,加载前面写好的 my.cnf 主从配置文件。

!warning 重启后必须重新获取 binlog 状态

容器重启之后,需要重新登录 mysql,执行 show master status; 拿到 binlog 文件名和 position 偏移量,后面从库配置要用到。

7. 查看主库 binlog 状态

bash 复制代码
[root@localhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44-log MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
sql 复制代码
MySQL [(none)]> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 154
     Binlog_Do_DB: school
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

字段说明

  1. File: mysql-bin.000001 :binlog 日志文件名,从库配置 MASTER_LOG_FILE 需要填这个
  2. Position: 154 :binlog 偏移位置,从库配置 MASTER_LOG_POS 需要填这个
  3. Binlog_Do_DB: school :主库只记录 school 库的二进制日志,对应 my.cnf 里 binlog-do-db=school

!warning 重要

主库一旦重启,File 和 Position 会发生变化 ,配置从库之前一定要重新执行 show master status\G; 拿到最新的值。这两个参数后面要复制到从库的 change master to 语句中。

示例后续从库要填写的片段:

sql 复制代码
CHANGE MASTER TO
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;

8. 从库配置并启动复制

bash 复制代码
[root@localhost ~]# docker restart mysql_slave
bash 复制代码
[root@localhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3307
sql 复制代码
MySQL [(none)]> 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;

MySQL [(none)]> start slave;

参数解释

  1. master_host='mysql_master'自定义网络/link 环境下,直接写主库容器名作为主机名,不需要写 IP
  2. master_user='backup':主库上创建的复制账号
  3. master_password='123456':复制账号密码
  4. master_log_file='mysql-bin.000001':主库 show master status 拿到的 binlog 文件名
  5. master_log_pos=154:主库 binlog 偏移位置
  6. master_port=3306容器内部端口,不是宿主机映射端口,填 3306,不要填宿主机的端口

start slave; 启动从库复制线程。

查看从库复制状态

sql 复制代码
show slave status\G;

重点看这两个条件全部为 Yes 才算主从成功:

sql 复制代码
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

!\[03_云原生/Docker/image/c15646a7780f0d29ff58408c4b380af1_MD5.jpg]

!note 排障方向

  • IO 线程 No:网络不通、账号密码错误、主机名解析失败
  • SQL 线程 No:主从数据不一致,主键冲突等问题
    !warning 小坑提醒

如果之前配置过主从,执行 change master to 前,先执行 stop slave; reset slave all; 清理旧配置,避免残留旧参数干扰。

三、常见报错排查

1. ERROR 1794:server-id 未配置或未生效

text 复制代码
ERROR 1794 (HY000): Slave is not configured or failed to initialize properly. You must at least set --server-id to enable either a master or a slave. Additional error messages can be found in the MySQL error log.

报错原因

核心:从库没有配置 server-id,或者 server-id 没生效

MySQL 5.7 做主从,不管主库还是从库,server-id 必须配置,且主从不能相同

  • 主库 my.cnf:server-id=1
  • 从库 my.cnf:server-id=2(不能和主库一样)

常见 4 种情况

  1. ✅ 写了 my.cnf,但是没有重启 mysql_slave 容器 ,配置没加载。你前面虽然改了 slave 的配置文件,但是没执行 docker restart mysql_slave,mysql 读取的还是旧配置,server-id 不存在。
  2. ❌ my.cnf 挂载/映射错误,docker 容器内 mysql 根本没有读到你的配置文件。docker 部署很容易踩这个坑:宿主机改了 my.cnf,但是容器没挂载上,容器内部配置没变。
  3. ❌ 从库 server-id 和主库 server-id 值一模一样,冲突。
  4. ❌ 配置写错,例如 server-id 写成 0;或者写在 [client] 段,不是写在 [mysqld] 段。

!warning server-id 必须写在 [mysqld] 下面,写在别的段落不生效。

排查步骤

  1. 进入从库容器内部,确认 mysql 读到的 server-id:
bash 复制代码
docker exec -it mysql_slave mysql -uroot -proot
show variables like 'server_id';
  • 如果返回 server_id | 0,代表配置完全没生效,就是上面的问题。
  1. 检查容器内 my.cnf:
bash 复制代码
docker exec -it mysql_slave cat /etc/mysql/my.cnf

确认 [mysqld] 下面有 server-id=2

  1. 修改完配置必须重启容器
bash 复制代码
docker restart mysql_slave
  1. 重启后,再登录 mysql,确认 server_id 不是 0,再执行:
sql 复制代码
stop slave;
reset slave all;
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

!tip 排查经验

docker mysql 镜像,如果宿主机挂载配置文件失败,宿主机改一万遍,容器 mysql 都不会读取,一定要进容器内部看配置,不要只看宿主机文件。

2. ERROR 3021:IO 线程运行中修改主从配置

text 复制代码
ERROR 3021 (HY000): This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD first.

报错原因

从库的 IO 复制线程还在运行,不能直接执行 change master to 修改主从配置。

change master to 用来修改主库地址、binlog 文件名、偏移量,必须先停止复制线程,不能在 IO 线程运行状态直接改。

完整正确操作顺序

sql 复制代码
-- 1.先停止全部 slave 线程
stop slave;

-- 如果只想停 io 线程,也可以 stop slave io_thread;

-- 2.清除旧的主从记录(多次调试强烈建议加上,避免残留脏数据)
reset slave all;

-- 3.现在再执行 change master to
change master to
master_host='mysql_master',
master_user='backup',
master_password='123456',
master_log_file='mysql-bin.000003',
master_log_pos=154,
master_port=3306;

-- 4.启动复制
start slave;

-- 5.查看状态
show slave status\G;

小知识点区分

  1. stop slave;:同时停止 IO 线程 + SQL 线程 (做 change master to 首选)
  2. stop slave io_thread;:只停止 IO 线程,SQL 线程继续回放已经拿到的 binlog
  3. reset slave all;:彻底清空从库所有主从配置,适合反复调试主从环境,改配置前推荐执行

!warning 踩坑提醒

如果你之前执行过 start slave;,只要没 stop,IO 线程就处于运行状态,直接跑 change master to 就报 3021 错误。每次重新修改主从信息,第一步先执行 stop slave;

四、命令速查

命令 作用
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7 运行 MySQL 容器并设置 root 密码
docker exec -it mysql mysql -uroot -p 容器内登录 MySQL(交互式输密码更安全)
docker restart mysql_master 重启容器使配置生效
docker network create mysql-net 创建自定义网络
docker network connect mysql-net 容器名 将已运行容器加入网络
show master status\G; 查看主库 binlog 文件名与位置
change master to ...; start slave; 从库配置并启动主从复制
show slave status\G; 查看从库复制状态(IO/SQL 均为 Yes 成功)
相关推荐
Brilliantwxx1 小时前
42525
运维
RisunJan1 小时前
Linux命令-vgdisplay(显示卷组详细属性)
linux·运维·数据库
Escalating_xu2 小时前
【Linux线程】线程控制全解析:终止、join/detach、cancel、线程栈与 NPTL(下篇)
java·linux·运维
白猫不黑2 小时前
从运维到网络安全:转行优势、路径与薪资前景全解析
运维·网络·web安全·网络安全·信息安全·渗透测试
草莓熊Lotso2 小时前
【Linux网络加餐】手动部署:SSH 与 Web 服务实战 + 底层原理全解析
linux·运维·网络·人工智能·python·langchain·ssh
禅口魔心2 小时前
RK3576开发——Docker部署
docker·嵌入式linux
刚入门的大一新生3 小时前
Linux-Linux的进程状态
linux·运维·服务器
随便做点啥3 小时前
32卡×4090 24GB,Qwen3.8-27B-FP8 集群部署报告
服务器·经验分享·docker·vllm
迪康coolmu4 小时前
企业文件外发防泄漏实践:从通道封堵到三层全链路管控
大数据·运维·网络·人工智能·安全·阿里云