1、MGR 前置介绍
阿里云RDS集群方案用的就是MGR模式!
1.1、什么是 MGR
- MGR(MySQL Group Replication)是MySQL 5.7.17版本诞生的,是MySQL自带的一个插件,可以机动部署。
- 包管数据一致性又可以主动切换,具备故障检测功能、支持多节点写入。
- 集群是多个MySQL Server节点共同组成的分布式集群,每个Server都有完备的副本,它是基于ROW格式的二进制日志文件和GTID特性。
1.2、MGR 优点
- 强一致性:基于原生复制及paxos协议的组复制技能,并以插件的方式提供,提供一致数据安全包管。
- 高容错性:只要不是大多数节点坏掉就可以继承工作,有主动检测机制,当差别节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处置惩罚,并且内置了主动化脑裂防护机制。
- 高扩展性:节点的新增和移除都是主动的,新节点加入后,会主动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点主动更新组信息,主动维护新的组信息。
- 高机动性:有单主模式和多主模式。单主模式下,会主动选主,所有更新操纵都在主上进行;多主模式下,所有server都可以同时处置惩罚更新操纵。工作中优先使用单主模式!
1.3、MGR 缺点
- 仅支持InnoDB表,并且每张表肯定要有一个主键,用于做write set的冲突检测。
- 必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set;主从状态信息存于表中(–master-info-repository=TABLE 、–relay-log-inforepository=TABLE),–log-slave-updates打开。
- MGR不支持大事务,事务大小最好不凌驾143MB,当事务过大,无法在5秒的时间内通过网络在组成员之间复制消息,则大概会怀疑成员失败了,然后将其驱逐出局。
- 目前一个MGR集群最多支持9个节点。
- 不支持外键于save point特性,无法做全局间的约束检测与部分事务回滚。
- 二进制日志不支持Binlog Event Checksum。
1.4、MGR 适用场景
- 金融买卖业务、重要数据存储、对主从一致性要求高的场景。
- 核心数据总量未过亿。
- 读多写少,如:互联网电商。
2、MySQL MGR 搭建流程
2.1、环境预备
本次集群搭建,我使用3台阿里云ECS服务器(CentOS 7.9,2核2G,20G硬盘),每台服务器都分配公网IP,开放安全组:22(SSH)、3306(MySQL)、24901(MGR)。我的服务器设置如下:
Master服务器(hostname:n0):172.21.180.98
Slave服务器1(hostname:n1):172.21.180.99
Slave服务器2(hostname:n2):172.21.180.100
2.2、搭建流程
2.2.1、设置系统环境
将Hosts文件写入n0/n1/n2节点与内网IP对应关系,后面设置采用域名访问:
- # 3台服务器都执行
- sudo cat > /etc/hosts <<-'EOF'
- 172.21.180.98 n0
- 172.21.180.99 n1
- 172.21.180.100 n2
- EOF
复制代码 分别为三台服务器依次设置主机名称,三台服务器执行命令:
- # 第1台服务器
- hostnamectl set-hostname n0
- # 第2台服务器
- hostnamectl set-hostname n1
- # 第3台服务器
- hostnamectl set-hostname n2
复制代码 2.2.2、安装 MySQL
下载 MySQL 官方YUM仓库源(这个并不是安装MySQL):
- # 3台服务器都执行
- cd /home/
- wget --no-check-certificate https://repo.mysql.com/mysql80-community-release-el7-5.noarch.rpm
- yum localinstall -y mysql80-community-release-el7-5.noarch.rpm
复制代码 修改仓库设置,将下图中gpgcheck置为0:
- vi /etc/yum.repos.d/mysql-community.repo
复制代码
安装 MySQL 8.0.26:
- # 3台服务器都执行
- yum install -y mysql-community-server-8.0.26
复制代码 2.2.3、设置启动 MySQL
主节点n0执行:直接CV就行,不要墨迹!
- # 修改 MySQL 配置
- sudo cat >> /etc/my.cnf <<-'EOF'
- # 使用mysql_native_password密码策略,防止navicat连不上mysql8
- default_authentication_plugin=mysql_native_password
- # 设置MySQL插件目录:MGR基于插件,必须设置插件路径
- plugin_dir=/usr/lib64/mysql/plugin
- # 服务器编号,Master=1
- server_id=1
- # 开启binlog的GTID模式(MGR强制要求)
- gtid_mode=ON
- # 开启后MySQL只允许能够保障事务安全,并且能够被日志记录的SQL语句被执行
- enforce_gtid_consistency=ON
- # 关闭binlog校验(MGR强制要求)
- binlog_checksum=NONE
- # 定义用于事务期间哈希写入提取的算法,组复制模式下必须设置为 XXHASH64。
- transaction_write_set_extraction=XXHASH64
- # 确定组复制恢复时是否应该应用 SSL,通常设置为“开”,但默认设置为“关”。
- loose-group_replication_recovery_use_ssl=ON
- # 服务器实例所在复制组名称,必须是有效的 UUID,所有节点必须相同。
- loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
- # 确定服务器是否应该在服务器启动期间启动组复制。
- loose-group_replication_start_on_boot=OFF
- # 为复制组中其他的成员提供的网络地址,指定为“主机:端口”的格式化字符串。
- # 很多人想当然认为端口应该是3306,起始不然,MGR需要开启新端口24901同步交换
- # 所以这里不要写错,同时,前面我们配置了hosts文件做了主机名与IP的映射,这里直接写主机名即可
- loose-group_replication_local_address="n0:24901"
- # 用于建立新成员到组的连接组成员列表。
- # 这个列表指定为由分隔号间隔的组成员网络地址列表,类似 host1:port1、host2:port2 的格式。
- # 同样采用n0~n2的主机名替代
- loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901"
- # 配置此服务器为引导组,这个选项必须仅在一台服务器上设置,
- # 并且仅当第一次启动组或者重新启动整个组时。成功引导组启动后,将此选项设置为关闭。
- loose-group_replication_bootstrap_group=OFF
- EOF
复制代码 从节点n1执行:直接CV就行,不要墨迹!
- sudo cat >> /etc/my.cnf <<-'EOF'
- default_authentication_plugin=mysql_native_password
- plugin_dir=/usr/lib64/mysql/plugin
- # 设置唯一的服务器编号
- server_id=2
- gtid_mode=ON
- enforce_gtid_consistency=ON
- binlog_checksum=NONE
- # 这个参数决定primary节点到secondary节点的请求是否为基于 RSA 密钥对的密码交换所需的公钥
- loose-group_replication_recovery_get_public_key=ON
- loose-group_replication_recovery_use_ssl=ON
- loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
- loose-group_replication_start_on_boot=OFF
- # 设置本机地址n1:24901
- loose-group_replication_local_address="n1:24901"
- loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901"
- loose-group_replication_bootstrap_group=OFF
- EOF
复制代码 从节点n2执行:直接CV就行,不要墨迹!
- sudo cat >> /etc/my.cnf <<-'EOF'
- default_authentication_plugin=mysql_native_password
- plugin_dir=/usr/lib64/mysql/plugin
- #设置唯一的服务器编号
- server_id=3
- gtid_mode=ON
- enforce_gtid_consistency=ON
- binlog_checksum=NONE
- #这个参数决定primary节点到secondary节点的请求是否为基于 RSA 密钥对的密码交换所需的公钥
- loose-group_replication_recovery_get_public_key=ON
- loose-group_replication_recovery_use_ssl=ON
- loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
- loose-group_replication_start_on_boot=OFF
- #设置本机地址n2:24901
- loose-group_replication_local_address="n2:24901"
- loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901"
- loose-group_replication_bootstrap_group=OFF
- EOF
复制代码 三台服务器,依次启动 MySQL
- # 3台服务器都执行
- systemctl start mysqld
复制代码 2.2.4、修改密码、设置主从同步
三台服务器,依次通过该命令,获取数据库毗连密码:
- # 获取数据库密码
- grep 'temporary password' /var/log/mysqld.log
复制代码 三台服务器,毗连到数据库控制台中:
- # 连接数据库
- mysql -uroot -p'密码'
复制代码 三台数据库控制台中,都执行下述命令(3台服务器都执行):
- # 修改root密码为asAS123456!
- ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'asAS123456!';
- # 创建rpl_user账户,此账户用于实现主从数据同步
- CREATE USER rpl_user@'%' IDENTIFIED BY 'asAS123456!';
- # 赋予主从同步权限
- GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
- # 创建一个远程连接用户,这个用户用在Navcate、JDBC登录的时候,直接用root登录不好
- create user 'remote'@'%' identified with mysql_native_password by 'asAS123456!';
- # 为remote用户赋予所有数据库资源的访问权限,熟悉grant的小伙伴可以自己调整
- grant all privileges on *.* to remote@'%';
- # 让刚才的修改生效
- FLUSH PRIVILEGES;
- # 删除已产生的Binlog
- # 一定要RESET MASTER,它会删除刚才已产生的Binlog
- # 因为刚才Binglog包含创建用户这种高权限操作,用于主从同步的rpl_user账户是没有权限执行的
- # 这就会导致RelayLog重放无法正确执行,导致从属服务器卡死在"RECEVERING"状态
- # 利用RESET MASTER删除这些无法执行的binlog,就没问题了
- RESET MASTER;
复制代码 2.2.5、安装 MGR 插件
在三台服务器的MySQL控制台中,安装MGR插件,执行命令:
- # 3台服务器都执行
- INSTALL PLUGIN group_replication SONAME 'group_replication.so';
复制代码 在主服务器的MySQL控制台上,执行下述命令:
- # 注意:只在主服务器上运行
- # 我们在 primary.cnf 配置文件中把 group_replication_bootstrap_group 参数设置成 OFF
- # 在 primary 服务器启动时并不会直接启动复制组,通过下面的命令动态的开启复制组是我们的集群更安全
- SET GLOBAL group_replication_bootstrap_group=ON;
- START GROUP_REPLICATION;
- SET GLOBAL group_replication_bootstrap_group=OFF;
复制代码 在两个从服务器MySQL控制台上,执行下述命令:
- # 指定主从账户与指定通信频道
- CHANGE MASTER TO MASTER_USER="rpl_user", MASTER_PASSWORD="asAS123456!" FOR CHANNEL 'group_replication_recovery';
- # 开启组网数据同步
- START GROUP_REPLICATION;
复制代码 当两个从节点都运行完毕后,运行下面SQL效果进行验证:
- SELECT * FROM performance_schema.replication_group_members;
复制代码 出现以下情况,每个节点都是ONLINE状态,分析集群搭建成功:
3、MySQL MGR 故障转移
上面已经将MySQL MGR集群搭建完毕,并且节点都是ONLINE状态。
3.1、主节点n0下线,重新推选
首先,在主服务器n0上执行停止mysql命令,如下:
此时,在从节点n1检察集群状态发现,n1被推选为主节点:
这是由于MGR集群推选策略为:
- 优先低版本节点
- 版本一样,优先权巨大的节点
- 版本与权重一样,按照 server uuid 的字母顺序选主
在n1从节点上,通过命令检察故障转移日志:
- # 查看MySQL日志
- tail -n 50 /var/log/mysqld.log
复制代码 n1日志解析如下:
- # n0:3306(主节点n0)从组中被移除掉
- [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306'
- # 重新选举新的 Primary 主节点
- [System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.'
- # n1:3306(从节点n1)被选举为主节点,执行之前未完成的事务处理
- [System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n1:3306 was elected. The new primary will execute all previous group transactions before allowing writes.'
- # 组成员目前只剩 n1:3306, n2:3306
- [System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n1:3306, n2:3306 on view 17172171443362674:4.'
- # 关闭 n1 节点的只读状态
- [System] [MY-013731] [Repl] Plugin group_replication reported: 'The member action "mysql_disable_super_read_only_if_primary" for event "AFTER_PRIMARY_ELECTION" with priority "1" will be run.'
- # 设置 super_read_only=OFF
- [System] [MY-011566] [Repl] Plugin group_replication reported: 'Setting super_read_only=OFF.'
- # 当前节点(n1)以主节点身份工作
- [System] [MY-011510] [Repl] Plugin group_replication reported: 'This server is working as primary member.'
复制代码 在n2从节点上,通过命令检察故障转移日志:
- # 查看MySQL日志
- tail -n 50 /var/log/mysqld.log
复制代码 n2日志解析如下:
- # n0:3306(主节点n0)从组中被移除掉
- [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306'
- # 重新选举新的 Primary 主节点
- [System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.'
- # n1:3306(从节点n1)被选举为主节点,执行之前未完成的事务处理
- [System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n1:3306 was elected. The new primary will execute all previous group transactions before allowing writes.'
- # 组成员目前只剩 n1:3306, n2:3306
- [System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n1:3306, n2:3306 on view 17172171443362674:4.'
- # 当前节点(n2)作为主节点(n1)的从成员身份工作
- [System] [MY-011511] [Repl] Plugin group_replication reported: 'This server is working as secondary member with primary member address n1:3306.'
复制代码 3.2、新主节点n1下线,集群不可用
当在新晋升的主节点n1上执行停止MySQL操纵:
此时,在n2上通过命令检察发现,n1主节点只管已经下线,但n2检察集群状态时还在显示,因为只有1个节点的情况下,少于n/2+1的规则,导致团体 MGR 集群失效,n2节点无法产生重新推选,同时n2的日志也不会有任何新内容产生:
- SELECT * FROM performance_schema.replication_group_members;
复制代码
3.3、恢复 MGR 集群
恢复流程很简朴,先将三台服务器的MySQL各自重启:
- # 3台服务器都执行
- systemctl restart mysqld;
复制代码 然后重复执行 2.2.4 ~ 2.2.5 章节流程即可恢复 MGR 集群。
4、单主模式和多主模式
4.1、模式介绍
4.1.1、单主模式
在单主模式下, 组复制具有主动选主功能,每次只有一个 server成员可以作为主节点。
单主模式 group 内只有一台节点可写可读,其他节点只可以读。对于group的部署,需要先跑起primary主节点,然后再跑起其他的节点,并把这些节点加进group。其他的节点就会主动同步primary节点上面的变化,然后将自己设置为只读模式。
当primary主节点意外宕机或者下线,在满意大多数节点存活的情况下,group内部发起推选,选出下一个可用的读节点,提升为primary节点。
4.1.2、多主模式
在多主模式下,所有的 MySQL 节点都可以同时担当读写操纵。group内的所有节点都是primary主节点,同时可以进行读写操纵,并且数据是最终一致的。
4.2、模式切换
之前我们搭建的 MySQL MGR 集群就是单主模式(默认),那么如何切换为多主模式呢?按照如下操纵进行。
4.2.1、单主 ——> 多主
从 n0 ~ n2 停止组复制,开启多主模式(3个节点都执行):
- # 停止组复制
- stop group_replication;
- # 是否启用单主模式,默认ON,OFF代表多主
- set global group_replication_single_primary_mode=OFF;
- # 是否开启条件检查,因为多主的约束更为严格,不符合要求的直接拒绝
- # 不支持外键的级联操作
- # 不支持“串行化Serializable”
- set global group_replication_enforce_update_everywhere_checks=ON;
复制代码 在 n0 主节点启用组复制:
- # 只在 n0 上执行
- SET GLOBAL group_replication_bootstrap_group=ON;
- START GROUP_REPLICATION;
- SET GLOBAL group_replication_bootstrap_group=OFF;
复制代码 在 n1,n2 节点上启用组复制:
- # 只在 n1, n2 上执行
- START GROUP_REPLICATION;
复制代码 此时,可以看到三台MySQL都是主节点:
- SELECT * FROM performance_schema.replication_group_members;
复制代码
4.2.2、多主 ——> 单主
从 n0 ~ n2 停止组复制,开启多主模式(3个节点都执行):
- # 停止组复制
- stop group_replication;
- # 是否开启条件检查,因为多主的约束更为严格,不符合要求的直接拒绝
- # 不支持外键的级联操作
- # 不支持“串行化Serializable”
- set global group_replication_enforce_update_everywhere_checks=OFF;
- # 是否启用单主模式,默认ON,OFF代表多主
- set global group_replication_single_primary_mode=ON;
复制代码 在 n0 主节点启用组复制:
- # 只在 n0 上执行
- SET GLOBAL group_replication_bootstrap_group=ON;
- START GROUP_REPLICATION;
- SET GLOBAL group_replication_bootstrap_group=OFF;
复制代码 在 n1,n2 节点上启用组复制:
- # 只在 n1, n2 上执行
- START GROUP_REPLICATION;
复制代码 此时,可以看到三台MySQL变成了主从模式:
- SELECT * FROM performance_schema.replication_group_members;
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |