介绍一下基本概念
🤔传统的主从复制
传统的主从复制架构,是由一个主节点和一个从节点组成,主从复制属于异步复制,当主节点提交了事务,会将数据写入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集群中