Bootstrap

在Centos Stream 9上Docker的实操教程(七) - Docker上实现MYSQL实现主从复制

在这里插入图片描述

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

前言

很多系统在我们日常使用中随着业务量的扩展,系统访问量增加,单台Mysql可能会负载过重,I/O频率过高等问题。轻则读写效率低,严重的可能会导致宕机数据丢失的问题,这时候就可以采用主从复制、读写分离可以提高数据库的可用性,减少单台MySQL数据库服务器的压力,提高数据库能更大的并发。

主从复制原理

在这里插入图片描述
从上图我们来了解一下Mysql主从复制的原理:主(Master)、从(salve)

  1. 客户端发起SQL操作Master数据变更(insert、update、delete)会记录到binlog中
  2. Salve从库连接Master主库创建Dump线程,随时监听binlog变化
  3. Master节点的binlog发生变化时,Dump线程会通知所有的Salve节点,并将相应的binlog内容推送给Slave节点
  4. I/O线程接收到 binlog 内容后,将内容写入到本地的 Relay-Log
  5. SQL线程读取I/O线程写入的relay-log,并且根据 relay-log 的内容对从数据库做对应的操作

实现主从复制注意要点:

主库开启binlog日志
设置server-id且主从不同
从库服务器能连通主库

MySQL主从复制的形式:

一主一从
一主多从
多主一从
双主复制
级联复制

本章节主要以Docker内容为主,Mysql主从复制相关内容就不再赘述了,感兴趣的可以关注评论,大家再一起探讨!

环境准备

大致大家有了对主从复制的一个理解后,我们开始实现Mysql一主二从;

端口号规划如下
3306(主) 数据卷 /mydata/mysql-master
3307(从) 数据卷 /mydata/mysql-slave1
3308(从) 数据卷 /mydata/mysql-slave2

实战大于理论

一主二从Mysql安装

Master主库安装

docker run -p 3306:3306 --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

slave1从库安装

docker run -p 3307:3306 --name mysql-slave1 \
-v /mydata/mysql-slave1/log:/var/log/mysql \
-v /mydata/mysql-slave1/data:/var/lib/mysql \
-v /mydata/mysql-slave1/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

slave2从库安装

docker run -p 3308:3306 --name mysql-slave2 \
-v /mydata/mysql-slave2/log:/var/log/mysql \
-v /mydata/mysql-slave2/data:/var/lib/mysql \
-v /mydata/mysql-slave2/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

检测容器是否成功运行
在这里插入图片描述

Master主库配置

设置主库配置文件,在宿主机 /mydata/mysql-master/conf 目录下新建my.cnf设置如下内容

[mysql]
default-character-set=utf8mb4
[mysqld]
#设置server_id,同一局域网中需要唯一
server_id=20
#指定不需要同步的数据库名称 binlog-do-db 为需要同步的数据库
binlog-ignore-db=mysql
#开启二进制日志功能
log-bin=micro-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7

使用指令重启容器使用配置生效 docker restart mysql-master

  • 进入容器 docker exec -it mysql-master /bin/bash
  • 进入数据库 mysql -u root -p 输入密码登陆

构建从库用户账户密码

-- 创建名slave为用户供从库连接
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
-- 授权表示可以从任意ip使用此用户名和密码连接到主数据库
GRANT REPLICATION SLAVE ON *.* to 'slave'@'%';
-- 刷新配置
FLUSH PRIVILEGES;

Slave从库配置

设置从库配置文件,在宿主机 /mydata/mysql-slave1/conf 目录下新建my.cnf设置如下内容,slave2同理

[mysql]
default-character-set=utf8mb4
[mysqld]
#设置server_id
server_id=17
#指定不需要同步的数据库名称
binlog-ignore-db=mysql  
#开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=micro-mysql-slave-bin  
#设置二进制日志使用内存大小(事务)
binlog_cache_size=1M  
#设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed  
#二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7  
#relay_log配置中继日志
relay_log=micro-relay-log-bin
#log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  
#slave设置为只读(具有super权限的用户除外)
read_only=1

启动Slave从库复制

首选我们在主库执行一下 show master status; 获取binlog日志名称 和日志偏移量, 从库开启复制所需的必要参数;
在这里插入图片描述
进入对应从库,配置主从连接关系 * 注意是在从库操作 执行以下SQlL

CHANGE MASTER TO 
MASTER_HOST='192.168.1.20',
MASTER_USER='slave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='micro-mysql-bin.000001',
MASTER_LOG_POS=156,
MASTER_CONNECT_RETRY=30,
MASTER_PORT=3306;

参数说明:

  • MASTER_HOST 主数据库的IP地址
  • MASTER_USER 在主库创建的同步数据用户名
  • MASTER_PASSWORD 在主库创建的同步数据用户密码
  • MASTER_LOG_FILE 主库的binlog日志名称
  • MASTER_LOG_POS binlog日志偏移量即从数据库从哪个位置开始复制数据
  • MASTER_CONNECT_RETRY 连接失败重试的时间间隔,单位为秒
  • MASTER_PORT 主库的运行端口

上述SQL执行完成开启从库复制,slave2配置和slave1一致这里就不再重复了;

-- 启动主从复制
start slave;

如需停止主从复制执行 stop slave;
如需清理掉之前的配置,重新配置 执行 reset slave all;

查看设置是否成功

-- 启动主从复制
show slave status \G; 

出现下图则证明主从复制设置成功
在这里插入图片描述
如果出现两个参数非YES的情况,注意观察 Last_IO_Error 的提示信息,如果出现
Authentication plugin ‘caching_sha2_password‘ reported error: Authentication requires sec 的异常问题,主要是因为8.0以后默认使用caching_sha2_password方式,因此需要将其改成mysql_native_password验证机制

解决思路一:修改Slave用户密码验证
ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

解决思路二:修改my.cnf 追加设置默认密码验证
default_authentication_plugin=mysql_native_password

测试验证

主库新建test表执行上一章中我们的student建表语句;

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '学生ID',
  `name` varchar(50) NOT NULL COMMENT '学生姓名',
  `gender` varchar(10) NOT NULL COMMENT '学生性别',
  `birthday` date NOT NULL COMMENT '学生生日',
  `address` varchar(100) NOT NULL COMMENT '学生住址',
  `phone` varchar(20) NOT NULL COMMENT '学生联系方式',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生信息表';

INSERT INTO `student` (`id`, `name`, `gender`, `birthday`, `address`, `phone`) VALUES (1, '小明', '男', '2023-06-16', '广州', '13700137000');
INSERT INTO `student` (`id`, `name`, `gender`, `birthday`, `address`, `phone`) VALUES (2, '小羊', '女', '2023-06-16', '广州', '13800126000');

在主库mysql-master容器 show databases;
在这里插入图片描述
验证Slave1从库和Slave2从库是否已经完成复制,登陆从库mysql后 show databases;

-- 选择数据库
use test;
-- 查询表信息
select * from student;

在这里插入图片描述
看到如上数据,证明本次我们使用Docker上实现MYSQL实现主从复制已经成功了~

读写分离推荐Apache ShardingSphere

数据库完成了主从复制后,在我们JAVA开发中可以使用Apache ShardingSphere作为读写分离的解决方案,如果大家对这个框架感兴趣可以留言评论,后续考虑出一期Apache ShardingSphere的使用教程。

结语

本章节主要对Mysql主从复制使用场景、Mysql主从复制的原理,最后使用Docker实现MYSQL实现主从复制,从主库到从库的配置,再实际的业务场景中,更多的应该是两台或多台应用服务器部署的Mysql进行主从,而非一个宿主机上两个mysql容器实现主从,当然大家只要跟着博主的代码内容,了解原理都能轻松上手!最后如果本章节内容对你有用,希望点赞收藏加关注!

;