MYSQL主从频频失效,醒醒吧,使用MGR集群不香吗

介绍一下基本概念

🤔传统的主从复制

传统的主从复制架构,是由一个主节点和一个从节点组成,主从复制属于异步复制,当主节点提交了事务,会将数据写入binlog日志中,从库执行relay log日志更新数据库,默认情况下实现主从数据的一致性

问题:

1、主从复制在5.6以前容易发生复制延迟
2、主从复制的最终一致性无法自行实现,即主节点会一直提交而不管从节点的状态,导致数据不一致
3、当主节点发生故障导致宕机时,无法在从节点中自行做主从切换选取新的主节点

基于上述问题使用半同步复制

概念

什么是半同步复制呢? 半同步复制就是在提交事务的时候加入一个同步的操作,保证从节点跟主节点的数据一致性 半同步复制是基于主从复制的,传统的主从复制,不理会从库的状态,主库不断更新数据。 但是半同步复制则是在主库进行提交的时候,需要从库做一个确认的操作,即确保从库把二进制日志写入到了中继日志之后才允许主库进行提交 如果从库出现了问题,长时间之后会自动回退到主从复制模式

了解到这里,你就能明白为什么要用MGR了

MGR具备以下几个特点:

vbnet 复制代码
1、mgr是基于shared-nothing模式,每个节点都有完整的数据备份,发生故障可以自动切换
2、mgr支持故障切换,即自动切换主节点
3、便捷的管理所有的节点,包括加入或者剔除节点
4、默认是最终一致性
5、支持单主模式、多主模式,推荐是使用单节点为主节点的模式
6、主节点提供读写权限,从节点提供只读权限

说了这么多总要实操一下,接下来教会大家如何去部署MGR集群

首先我们要准备三台服务器分别是mgr01、mgr02、mgr03

三台节点执行:

首先是安装wget

yum install wget

接下来安装MYSQL YUM Repository

sql 复制代码
wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm
rpm -ivh mysql80-community-release-el7-5.noarch.rpm

现在可以开始安装MYSQL服务端了,使用--nogpgcheck跳过检查

css 复制代码
yum install -y mysql-server  --nogpgcheck

安装完成之后我们可以启动mysql服务并且找到临时密码

sql 复制代码
systemctl start mysqld
c 复制代码
grep 'temporary password' /var/log/mysqld.log

通过获取临时密码的命令可以获取到如下页面,这一串就是我们的密码

接下来我们登录mysql并且修改密码

css 复制代码
mysql -u root -p

输入我们的临时密码进入以下界面

执行以下命令修改密码

sql 复制代码
ALTER USER 'root'@'%' IDENTIFIED BY '!TYJKasbxcs'

三台节点执行

此时我们需要去修改my.cnf文件,由于采用的是默认安装的mysql,存储位置在默认目录,可以通过find命令查找

arduino 复制代码
find / -name mysql

以下是我修改后的my.cnf文件

主要关注

bash 复制代码
我们首先需要在三台节点上绑定域名映射
修改每台节点的/etc/hosts文件配置ip 域名
ini 复制代码
server_id 每台节点一个id
loose-group_replication_group_name 三台节点保持组名一致
loose-group_replication_local_address 节点的通信地址
loose-group_replication_group_seeds 三台节点的通信地址,保持一致
report_host=mgr02 当前节点
report_port=3306  当前节点的端口

这是mgr02的配置

ini 复制代码
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

group_replication_recovery_get_public_key=1

relay_log_info_repository = TABLE
master_info_repository    = TABLE

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid


port=3306
basedir=/usr
#datadir=/mysql/data_mgr_8.0/
###socket=/mysql/data_mgr_8.0/mysql.sock
###pid_file=/mysql/data_mgr_8.0/mysql.pid
##
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
##
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
##master_info_repository=TABLE
###relay_log_info_repository=TABLE
##
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "mgr02:33061"
loose-group_replication_group_seeds= "mgr01:33061,mgr02:33061,mgr03:33061"
loose-group_replication_bootstrap_group=OFF
##
report_host=mgr02
report_port=3306

这是mgr03的配置

ini 复制代码
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

relay_log_info_repository = TABLE
master_info_repository    = TABLE

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid


port=3306
basedir=/usr
#datadir=/mysql/data_mgr_8.0/
##socket=/mysql/data_mgr_8.0/mysql.sock
##pid_file=/mysql/data_mgr_8.0/mysql.pid
#
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
#
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
#master_info_repository=TABLE
##relay_log_info_repository=TABLE
#
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "mgr03:33061"
loose-group_replication_group_seeds= "mgr01:33061,mgr02:33061,mgr03:33061"
loose-group_replication_bootstrap_group=OFF
#
group_replication_recovery_get_public_key=1
report_host=mgr03
report_port=3306

相应的mgr01就不提供了

三台节点都执行

接下来我们重启mysql

systemctl restart mysqld

登录mysql之后增加mgr的复制用户,用于进行数据同步

ini 复制代码
SET SQL_LOG_BIN=0;
CREATE USER mgruser@'%' IDENTIFIED BY 'mgruser';
GRANT REPLICATION SLAVE ON *.* TO mgruser@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='mgruser', MASTER_PASSWORD='mgruser' FOR CHANNEL 'group_replication_recovery';

然后我们下载mgr插件

arduino 复制代码
install PLUGIN group_replication SONAME 'group_replication.so';

下载完成之后我们可以通过show plugins语句查看

选择一个节点作为主节点进行操作

接下来是重头戏,一旦成功直接颅内爽飞 启动mgr单主节点模式

ini 复制代码
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

好吧,你是不是启动失败了,别问我怎么知道 我们可以查看错误日志/var/log/mysqld.log

很明显他说33061这个端口有问题,猜一猜是不是防火墙没关 我们关闭防火墙,好像也没用

arduino 复制代码
systemctl stop firewalld
systemctl disable firewalld

解决措施:我们可以开放端口

bash 复制代码
# 1.关闭SELinux,不太安全,不特别推荐
setenforce 0
# 2.开放通讯端口(推荐)
yum install -y policycoreutils-python
semanage port -a -t mysqld_port_t -p tcp 33061

接下来我们继续在主节点执行

ini 复制代码
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

另外两台从节点执行,这条命令可让从节点加入到mgr组中

ini 复制代码
START GROUP_REPLICATION;

执行完之后我们就可以看到mgr的信息,此时可以发现三台节点都加入进去了

sql 复制代码
SELECT * FROM performance_schema.replication_group_members;

此时可以在主节点创建表并存入数据,如果发现从节点看不到相应的库表,则去检查复制用户mgruser的权限,让他拥有所有库表的权限,在mysql中执行

scss 复制代码
grant all privileges on *.* to mgruser@'%';
flush privileges;

此时可以看到数据同步了

接下来我们模拟主节点宕机 通过停止主节点模拟

主节点mgr02中执行

arduino 复制代码
systemctl stop mysqld

我们可以看到主节点变成了mgr01,此时实现了自动切换主节点

mgr02中执行

接下来我们将mgr02进行恢复

sql 复制代码
systemctl start mysqld

我们发现并不会自动加入到组中,此时需要我们手动加入这台节点mgr02

sql 复制代码
start group_replication

执行完之后再次执行

sql 复制代码
SELECT * FROM performance_schema.replication_group_members;

我们可以发现mgr02加入进了mgr集群中

至此我们完成了最简单的mgr集群的部署

ps,上述有不正确的地方欢迎各位客官指正,共同进步

相关推荐
工业甲酰苯胺8 小时前
分布式系统架构:服务容错
数据库·架构
Java程序之猿10 小时前
微服务分布式(一、项目初始化)
分布式·微服务·架构
小蜗牛慢慢爬行12 小时前
Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
java·架构·hibernate
思忖小下14 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
一个儒雅随和的男子21 小时前
微服务详细教程之nacos和sentinel实战
微服务·架构·sentinel
腾讯云开发者21 小时前
AI时代,需要怎样的架构师?腾讯云架构师峰会来了!
架构
Hello Dam1 天前
面向微服务的Spring Cloud Gateway的集成解决方案:用户登录认证与访问控制
spring cloud·微服务·云原生·架构·gateway·登录验证·单点登录
AI人H哥会Java1 天前
【Spring】Spring的模块架构与生态圈—Spring MVC与Spring WebFlux
java·开发语言·后端·spring·架构
小屁不止是运维1 天前
麒麟操作系统服务架构保姆级教程(二)ssh远程连接
linux·运维·服务器·学习·架构·ssh