容器化部署MySQL8.0.43,主从复制流程(非生产环境)

写作说明 本人目前处于运维入门学习阶段,本文仅作为个人实操学习笔记分享,目的是通过手动搭建 MySQL 双向双主复制,吃透 binlog、主从同步、容器部署等底层基础知识点。

  1. 本方案仅适用于测试、学习环境;原生异步双主存在无冲突检测、无自动故障转移、两节点存在脑裂风险等短板,高并发正式业务不建议直接使用;
  2. MySQL 官方成熟高可用方案为 MGR/InnoDB Cluster,需要至少 3 台节点,本人后续会继续学习并补充相关实操笔记;

环境:
宿主机系统:龙蜥8.10

mysql:8.0.43

第一步:获取镜像mysql8.0.43

第二步:获取默认配置文件

启动容器,把配置文件copy到本地,(node1和node2同步操作)

# 在/opt/下创建一个mysql目录 
mkdir -p /opt/mysql
# 临时启动一下mysql
docker run -d \
	--name mysql-master \
	-p 3306:3306 \
	-e MYSQL_ROOT_PASSWORD=123456 \
	mysql:8.0.43

# 把数据和配置目录copy到本地

node1,node2上分别执行 :

docker cp mysql-master:/etc/my.cnf /opt/mysql/my.cnf

第三步:配置启动主库

1,在node1中修改my.cnf

vim /opt/mysql/my.cnf #进行编辑

[mysqld]
#mysql 服务ID,保证整个集群环境中唯一,取值范围:1 – 2的32次方-1,默认为1
server-id=1
#是否只读,1 代表当前服务器只读(不能做增删改操作), 0代表读写
read-only=0
# 设置日志格式,默认值ROW。row(记录行数据)  statement(记录sql)  mixed(混合模式)
binlog_format=STATEMENT
# 二进制日志名,默认binlog
log-bin=master_binlog
# 设置需要复制的数据库,默认复制全部数据库
#binlog-do-db=test
# 设置不需要复制的数据库
# binlog-ignore-db=test




skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/

2、在node1上启动主库

先删除上一次创建过的docker容器:

docker rm -f mysql-master

再启动主库

docker run -d \
	--name mysql-master \
	-p 3306:3306 \
	-e MYSQL_ROOT_PASSWORD=123456 \
	-v /opt/mysql/mysql_data:/var/lib/mysql \
	-v /opt/mysql/my.cnf:/etc/my.cnf \
	--restart=always \
	--privileged=true \
	mysql:8.0.43

3、创建主备账号:

先进入mysql:

docker exec -it mysql-master mysql -uroot -p
 运行:

CREATE USER 'backups'@'%' IDENTIFIED BY 'backups';

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'backups'@'%';

GRANT BACKUP_ADMIN ON *.* TO 'backups'@'%';
# 使用备份锁获取位置(代替FLUSH TABLES,不阻塞DML!)
LOCK INSTANCE FOR BACKUP;
# 获取主库状态
SHOW MASTER STATUS\G

获取复制源二进制日志坐标

要配置副本在正确的点开始复制过程,您需要在二进制日志中记下源的当前坐标。要获取源二进制日志坐标,通过使用命令行客户端连接到源来启动源上的会话

记录一下File和Position,在从库配置同步源的时候需要用到

第三步:配置启动从库

1、配置从库并启动

在node2上执行vim my.cnf ,编辑以下配置

[mysqld]
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=2
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin
#是否只读,1 代表只读, 0 代表读写。对于从库来说,我们只需要从从库中进行查询即可,不需要从从库中进行写入操所>以直接把read-only设置为1就行了。
read-only=1
#二进制文件的名称
#log-bin=binlog
# 设置日志格式,默认值ROW。row(记录行数据)  statement(记录sql)  mixed(混合模式)
binlog_format=STATEMENT

skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/

2、启动从库:

启动前删除先删除上一次创建过的docker容器:

docker rm -f mysql-master

再启动从库

docker run -d \
        --name mysql-slave --network host\
        -p 3306:3306 \
        -e MYSQL_ROOT_PASSWORD=123456 \
        -v /opt/mysql/mysql_data:/var/lib/mysql \
        -v /opt/mysql/my.cnf:/etc/my.cnf \
        --restart=always \
        --privileged=true \
        mysql:8.0.43

3、使用复制用户请求服务器公钥

这一步是为了避免ERROR:Authentication plugin ‘caching_sha2_password‘ reported error:Authentication错误的;

从库内执行:docker exec -it mysql-slave bash 以进入bash

在从库的容器内的bash执行

mysql -u backups -pbackups -h <主库ip> -P3306 --get-server-public-key

进入后退出到bash,用root账户继续登录:mysql -uroot -p

设置从库的同步源

CHANGE REPLICATION SOURCE TO
SOURCE_HOST='--------',
SOURCE_USER='backups',
SOURCE_PASSWORD='backups',
SOURCE_LOG_FILE='----------',
SOURCE_LOG_POS=---;

-----部分自行填入

管理从库的同步复制状态

# 暂停副本上的复制
mysql> STOP REPLICA;
# 开始副本上的复制
mysql> START REPLICA;
# 检查单个副本的状态
SHOW REPLICA STATUS\G


Replica_IO_State:副本的当前状态
Replica_IO_Running:读取源二进制日志的 I/O(接收器)线程是否正在运行。通常情况下为Yes,除非您尚未启动复制或已明确停止复制,否则您希望此线程处于运行状态STOP REPLICA。
Replica_SQL_Running:执行中继日志中事件的SQL线程是否正在运行。与I/O线程一样,这通常应该是Yes。
Last_IO_Error, Last_SQL_Error:处理中继日志时I/O(接收方)和SQL(应用方)线程记录的最后错误。理想情况下,这些应该是空白的,表示没有错误。
Seconds_Behind_Source:复制SQL(应用程序)线程处理源二进制日志所落后的秒数。数字过大(或不断增加)可能表示副本无法及时处理来自源的事件。值为0,Seconds_Behind_Source通常可以解释为副本已赶上源;但在某些情况下这并不完全正确。例如,如果源和副本之间的网络连接中断,但复制 I/O(接收器)线程尚未注意到这一点,即设置的时间段 replica_net_timeout尚未过去,则可能会发生这种情况。Seconds_Behind_Source无法准确反映情况。当复制 SQL(应用程序)线程赶上 I/O 时, Seconds_Behind_Source显示 0;但当复制 I/O(接收器)线程仍在排队新事件时,Seconds_Behind_Source可能会显示较大的值,直到复制应用程序线程完成执行新事件。当事件具有旧时间戳时尤其可能出现这种情况;在这种情况下,如果您在相对较短的时间内执行SHOW REPLICA STATUS 多次,您可能会看到此值在 0 和相对较大的值之间反复来回变化。

在从库执行 SHOW REPLICA STATUS\G 之后看下面的Replica_IO_State状态显示:Waiting for source to send event, Replica_IO_Running: Yes,Replica_SQL_Running: Yes,说明复制状态正常

在主库执行 SHOW PROCESSLIST \G;

检查正在运行的进程列表来检查连接的副本的状态。副本连接包含Command字段为:Binlog Dump SHOW PROCESSLIST \G;

第四步:测试

1、连接主库和从库

2、在主库创建test库和user表,并插入三条数据

# 创建test库
create database test;
use test;
# 在test库中创建user表
create table user(
  id int(11) primary key not null auto_increment,
  name varchar(50) not null,
  sex varchar(1),
  age int(11)
)engine=innodb default charset=utf8mb4;
# 插入三条数据
insert into user(id,name,sex,age) values(null,'张三', '1',18),(null,'李四','0',19),(null,'王五','1',20);

3、查看node2上的从库是否同步至此,主从同步已经完成,如果需要一主多从,只需要在多部署几个从库,按照上面从库的部署方式就可以了!

创作过程参考:mysql主从复制详细部署 - SunArmy - 博客园

在原有教学上,增添了部分命令使得能与当前版本所适配(比如启动从库时的 --network host),对原有的教程进行更细致的说明

posted @ 2026-07-24 20:09  GuiGui321  阅读(7)  评论(0)    收藏  举报