侧边栏壁纸
  • 累计撰写 57 篇文章
  • 累计创建 23 个标签
  • 累计收到 4 条评论

MySQL MGR

cluski
2022-03-19 / 0 评论 / 0 点赞 / 298 阅读 / 9,492 字
温馨提示:
本文最后更新于 2022-03-20,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

MySQL MGR

1 MGR集群模式介绍

​ MySQL是目前最流行的开源关系型数据库,国内金融行业也开始全面使用,其中MySQL 5.7.17提出的MGR(MySQL Group Replication)既可以很好的保证数据一致性又可以自动切换,具备故障检测功能、支持多节点写入,MGR是一项被普遍看好的技术。

​ MGR(MySQLrGroup Replication)是MySQL自带的一个插件,可以灵活部署。MySQL MGR集群是多个MySQL Server节点共同组成的分布式集群,每个Server都有完整的副本,它是基于ROW格式的二进制日志文件和GTID特性。

image-20220319141324547

1.1 MGR的优点

  1. 强一致性,基于原生复制及paxos协议的组复制技术,并以插件的方式,提供一致数据安全保证;

image-20220319141431587

  1. 高容错性,只要不是大多数节点就可以继续工作,有自动监测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者先得原则处理,并且内置了自动化脑裂防护机制;

image-20220319141612016

  1. 高扩展性,节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,知道新节点和其他节点保持一致,如果某节点被移除,其他节点自动更新信息,自动维护新的组信息;
  2. 高灵活性,有单主模式和多主模式,单主模式下,所有更新操作都在主上进行;多主模式下,所有server都可以同时处理更新操作。

1.2 MGR的使用约束

  1. 仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测;
  2. 必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与writeset;主从状态信息存于表中(--master-info-repository=TABLE、--relay-log-info-repository=TABLE),--log-slave-updates打开;
  3. MGR不支持大事务,事务大小最好不超过143MB,当事务过大,无法在5秒的时间内通过网络在组成员间复制消息,则可能会怀疑成员失败了,然后将其驱逐出局
  4. 目前一个MGR集群最多支持9个节点
  5. 不支持外键于save point特性,无法做全局间的约束检测与部分事务回滚
  6. 二进制日志不支持Binlog Event Checksum

1.3 MGR适用场景

  1. 金融交易,重要数据存储,对主从一致性要高的场景
  2. 核心数据总量未过亿
  3. 读多写少的应用场景,如互联网电商

2 MGR集群搭建

2.1 集群搭建过程

  1. 安装MySQL8.0(自行百度)

  2. 设置网络相关

    # 修改hosts
    cat >> /etc/hosts << EOF
    10.206.0.6 n0
    10.206.0.16 n1
    10.206.0.4 n2
    EOF
    
    # 修改对应的主机名
    hostnamectl set-hostname n0
    hostnamectl set-hostname n1
    hostnamectl set-hostname n2
    
    # 大坑1:
    # 临时关闭selinux防火墙,开启端口将无法访问,开发环境可以这样用
    # 生产环境这块安全配置麻烦点,咱们后面再说
    setenforce 0
    
    # 放行端口,3306MySQL默认端口,24901MGR通信端口
    firewall-cmd --zone=public --add-port=3306/tcp --permanent
    firewall-cmd --zone=public --add-port=24901/tcp --permanent
    firewall-cmd --reload
    
    
  3. 调整配置文件

    • Master节点
    # 安装完成,追加mysql
    sudo cat >> /etc/my.cnf << 'EOF'
    # 使用mysql_native_password密码策略,方式navicat连不上MySQL
    default_authentication_plugin = mysql_native_password
    # 设置MySQL插件的所在目录,因为MGR基于插件,所以必须设置插件路径
    plugin_dir = /usr/lib64/mysql/plugin
    
    # 服务器编号
    server_id = 1
    # 开启binlog的GTID模式
    gtid_mode = ON
    # 开启后MySQL只允许能够保证事务安全,并且能够被日志记录的SQL语句被执行
    enforce_gtid_consistency = ON
    # 关闭binlog校验
    binlog_checksum = NONE
    
    # 定义用于事务期间哈希写入提取的算法,组复制模式下必须设置为 XXHASH64
    transaction_write_set_extraction = XXHASH64
    # 确定组复制恢复时是否应该应用SSL,通常设置为开,但是默认设置为关
    loose-group_replication_recovery_use_ssl = ON
    # 该服务器的实例所在复制组的名称,必须是有效的UUID,所有节点必须同步
    loose-group_replication_group_name = "97fdde72-4954-4790-b757-9f861063a77e"
    # 确定服务器是否应该在服务启动期间开启组复制
    loose-group_replication_start_on_boot = OFF
    
    # 大坑2:
    # 为复制组中其他的成员提供的网络地址,指定为“主机:端口”的格式化字符串。
    # 很多人想当然认为端口应该是3306,起始不然,MGR需要开启新端口24901同步交换
    # 所以这里不要写错,同时,前面我们配置了hosts文件做了主机名与IP的映射,这里直接写主机名即可
    loose-group_replication_local_address = "n0:24901"
    
    # 用于建立新成员到组的连接组成员列表。
    # 这个列表指定为由分隔号间隔的组成员网络地址列表,类似 host1:port1、host2:port2 的格式。
    # 同样采用no~n2的主机名替代
    loose-group_replication_group_seeds = "n0:24901,n1:24901,n2:24901"
    # 配置此服务器为引导组,这个选项必须仅在一台服务器上设置,
    # 并且仅当第一次启动组或者重新启动整个组时。成功引导组启动后,将此选项设置为关闭。
    loose-group_replication_bootstrap_group = OFF
    EOF
    
    # 启动MySQL
    systemctl start mysqld
    
    • Replication节点-1
    # 安装完成,追加mysql
    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 = "97fdde72-4954-4790-b757-9f861063a77e"
    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
    
    # 启动MySQL
    systemctl start mysqld
    
    • Replication节点-2
    # 安装完成,追加mysql
    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 = "97fdde72-4954-4790-b757-9f861063a77e"
    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
    systemctl start mysqld
    
  4. 登录mysql,进行修改密码并设置主从同步账号

    # 修改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@'%';
    
    # 创建一个远程链接用户,这用户用在Navicat、JDBC登录的时候,直接用root不好
    create user 'remote'@'%' identified with mysql_native_password by 'asAS123456!';
    # 为remote用户赋予权限
    grant all privileges on *.* to remote@'%';
    
    FLUSH PRIVILEGES;
    
    # 大坑3:
    # 删除已经产生的binlog
    # 一定要RESET MASTER,他会删除刚才已经产生的binlog
    # 因为刚才binlog包含创建这种高权限操作,用于主从同步的rpl_user账户是没有权限执行的
    # 这回导致RelayLog重放无法正确执行,导致从属服务器卡死在RECEVERING状态
    # 利用RESET MASTER删除这些无法执行的binlog,就没有问题了
    RESET MASTER;
    
  5. 安装MGR插件

    INSTALL PLUGIN group_replication SONAME 'group_replication.so';

    安装完成之后可以查看插件是否已经安装完成:

    SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'group_replication' \G

image-20220319152748600

  1. master服务器上运行以下命令:

    SET GLOBAL group_replication_bootstrap_group = ON;
    START GROUP_REPLICATION;
    SET GLOBAL group_replication_bootstrap_group = OFF; 
    
  2. replication服务器上运行以下命令:

    CHANGE MASTER TO MASTER_USER="rpl_user", MASTER_PASSWORD="asAS123456!" FOR CHANNEL 'group_replication_recovery';
    START GROUP_REPLICATION;
    
  3. 验证是否成功:SELECT * FROM performance_schema.replication_group_members;

image-20220319222923251

2.2 集群故障排查

  1. 网络不通

image-20220319223358224

  1. 事务进度不一致

image-20220319223421054

解决办法:从属服务器停止,Reset binlog,重新同步

STOP GROUP_REPLICATION;
RESET MASTER;
CHANGE MASTER TO MASTER_USER="rpl_user", MASTER_PASSWORD="asAS123456!" FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;
  1. 无法执行create user...

image-20220319223552393

3 MGR故障转移实验

选举策略:

  • 优先低版本的节点
  • 如果版本一样,优先权重大的节点
  • 如果版本与权重一样的,按照server uuid的字母顺序选主
  1. 既有的集群:

    可以看到n2的member uuid比n1小,所以按理来说n0关闭之后,n2将成为新的主节点

image-20220319225409164

  1. 将n0关闭,查新新的集群信息:

image-20220319225533531

并且查看n2节点的log可以看到以下内容:

# 将n0从group中移除,重新选主
2022-03-19T14:50:19.619327Z 0 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306'
2022-03-19T14:50:19.619347Z 0 [System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.'
# n2节点被选举为新的主,执行之前未完成的事务处理
2022-03-19T14:50:19.619424Z 0 [System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n2:3306 was elected. The new primary will execute all previous group transactions before allowing writes.'
# 当前group成员变更为n1、n2
2022-03-19T14:50:19.619565Z 0 [System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n2:3306, n1:3306 on view 16476998177917418:6.'
# 关闭n2节点的只读状态,设置super_read_only=OFF
2022-03-19T14:50:19.620327Z 19 [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.'
2022-03-19T14:50:19.620443Z 19 [System] [MY-011566] [Repl] Plugin group_replication reported: 'Setting super_read_only=OFF.'
# 自动启用故障转移
2022-03-19T14:50:19.620471Z 19 [System] [MY-013731] [Repl] Plugin group_replication reported: 'The member action "mysql_start_failover_channels_if_primary" for event "AFTER_PRIMARY_ELECTION" with priority "10" will be run.'
# n2节点作为主节点开始工作
2022-03-19T14:50:19.620906Z 40 [System] [MY-011510] [Repl] Plugin group_replication reported: 'This server is working as primary member.'

n1节点可以看到以下log:

# 将n0从group中移除,重新选主
2022-03-19T14:50:19.619733Z 0 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306'
2022-03-19T14:50:19.619765Z 0 [System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.'
# n2节点被选举为新的主,执行之前未完成的事务处理
2022-03-19T14:50:19.619804Z 0 [System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n2:3306 was elected. The new primary will execute all previous group transactions before allowing writes.'
# 当前group成员变更为n1、n2
2022-03-19T14:50:19.619984Z 0 [System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n2:3306, n1:3306 on view 16476998177917418:6.'
# n1节点作为n2节点的从节点开始工作
2022-03-19T14:50:19.620549Z 34 [System] [MY-011511] [Repl] Plugin group_replication reported: 'This server is working as secondary member with primary member address n2:3306.'

如果继续将n2也下线的话,会发现尽管n2已经下线,但是n1查看集群状态时还显示在,是因为只有1个节点的情况下,少于n/2+1的规则,导致整体MGR集群失效,n1节点无法重新选举,同时n1的日志也不会有任何新的内容。

整体回复集群

按照n1,n2,n0的顺序重新加入MGR集群,重新运行以下命令:

START GROUP_REPLICATION;

4 单主模式与多主模式

​ 在单主模式下,组复制具有自动选主功能,每次只有一个server成员接受更新。单写模式group内只有一台节点可写可读,其他节点只可以读。对于group的部署,需要先跑起prmary节点,然后再跑起其他的节点,并把这些点加进group。其他的节点就会自动同步primary节点上面的变化,然后将自己设置为只读模式。当primary节点意外宕机或者下线,在满足大多数节点存活的情况下,group内部发起选举,选出下一个可用的读节点,提升为primary
节点。primary选举根据group内剩下存活节点的UUID按字典序升序来选择,然后选择排在最前的节点作为新的primary节点。

​ 在多主模式下,所有的 server 成员都可以同时接受更新。group内的所有机器都是primary节点,同时可以进行读写操作,并且数据是最终一致的。

单主模式

image-20220319231918862

多主模式

image-20220319231912881

4.1 运行时切换为多主模式

  1. n0~n2节点停止组复制,并开启多主模式
stop group_replication;
# 是否启用多主模式,默认ON,OFF代表多主
set global group_replication_single_primary_mode=OFF;
# 是否开启条件检查,因为多主的约束更加严格,不符合要求的直接拒绝
# 不支持外键的级联操作
# 不支持“串行化Serializable”
set global group_replication_enforce_update_everywhere_checks=ON;
  1. n0节点引导启动组复制
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF; 
  1. n1,n2启用组复制,加入MGR集群
START GROUP_REPLICATION;

可以看到所有的节点都编程了primary节点

image-20220319232544351

4.2 运行时切回单主模式

  1. 所有节点停止组复制,切回单主模式
stop group_replication;
set global group_replication_enforce_update_everywhere_checks=OFF;
set global group_replication_single_primary_mode=ON;
  1. 其他的一样

在设计上可以和应用层结合起来,有两种部署模式:分别为应用层双活和数据库双活,应用层双活和数据库单活

  1. MGR集群多活架构

​ 基于MGR的多活特性,数据的写入可以在多个节点之间复制,实现数据的强一致性需求,并且在节点通信出现延迟的情况下,会自动实现服务降级。对于此类方案,我们可以采用同机房多写,同城异机房只读的方案。

image-20220319233229309

  1. 双主模式的多活

​ 两个节点均可以写入数据,可以实现跨机房的数据复制,延迟较低,在业务层需要做隔离,在故障发生时能够快速切换到同机房的Slave节点。此方案对于两个IDC机房的场景中较为实用,但是机房多活的场景不适合。

image-20220319233327148

  1. 业务交叉的双活方案

5 ProxySQL

image-20220319233511230

image-20220319233920750

image-20220319234020822

image-20220319234101257

image-20220319234350539

image-20220319234517787

0

评论区