🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
在Centos Stream 9上Docker的实操教程 - Docker上实现Mysql主从复制
前言
很多系统在我们日常使用中随着业务量的扩展,系统访问量增加,单台Mysql可能会负载过重,I/O频率过高等问题。轻则读写效率低,严重的可能会导致宕机数据丢失的问题,这时候就可以采用主从复制、读写分离可以提高数据库的可用性,减少单台MySQL数据库服务器的压力,提高数据库能更大的并发。
主从复制原理
从上图我们来了解一下Mysql主从复制的原理:主(Master)、从(salve)
- 客户端发起SQL操作
Master
数据变更(insert、update、delete)会记录到binlog中 Salve
从库连接Master
主库创建Dump线程,随时监听binlog变化- 当
Master
节点的binlog发生变化时,Dump线程会通知所有的Salve
节点,并将相应的binlog内容推送给Slave
节点 - I/O线程接收到 binlog 内容后,将内容写入到本地的 Relay-Log
- 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容器实现主从,当然大家只要跟着博主的代码内容,了解原理都能轻松上手!最后如果本章节内容对你有用,希望点赞收藏加关注!