【Mysql】——MySQL 5.7 MGR(单主模式)

一、前言

       mysql应该是广大开发们用的最多的数据库了。单节点mysql没啥好说的,官方文档看起来就行了。不过对于集群来说,高可用这些就有点迷糊了,今天这个文章只是浅层次的总结一下。在5.7.17的官方文档中有详细地描述如何设置Single-Primary MGR的方法。Deploying Group Replication in Single-Primary Mode(https://dev.mysql.com/doc/refman/5.7/en/group-replication-deploying-in-single-primary-mode.html)

      MGR(MySQL Group Replication)是MySQL官方在5.7.17版本引进的一个数据库高可用与高扩展的解决方案,以插件形式提供,实现了分布式下数据的最终已执行,总结MGR的特点如下:

  • 高一致性:基于分布式paxos协议实现组复制,保证数据一致性
  • 高容错性:自动检测机制,只要不是大多数节点都宕机就可以继续工作,内置防脑裂保护机制;
  • 高扩展性:节点的添加与移除会自动更新组成员信息,新节点加入后,自动从其他节点同步增量数据,知道与其他节点数据一致;
  • 高灵活性:提供单住和多主模式,单主模式在主库宕机后能够自动选主,所有写入都在主节点进行,多主模式支持多节点写入。

二、知识点

       主从复制,一主多从,主库提供读写功能,从库提供只读功能。当一个事务在master 提交成功时,会把binlog文件同步到从库服务器上落地为relay log给slave端执行,这个过程主库是不考虑从库是否有接收到binlog文件,有可能出现这种情况,当主库commit一个事务后,数据库发生宕机,刚好它的binlog还没来得及传送到slave端,这个时候选任何一个slave端都会丢失这个事务,造成数据不一致情况。 为了避免出现主从数据不一致的情况,MySQL引入了半同步复制,添加多了一个从库反馈机制,即半同步复制。这个有两种方式设置:

  • 主库执行完事务后,同步binlog给从库,从库ack反馈接收到binlog,主库提交commit,反馈给客户端,释放会话;
  • 主库执行完事务后,主库提交commit ,同步binlog给从库,从库ack反馈接收到binlog,反馈给客户端,释放会话; 

但是,虽然满足了一主多从,读写分析,数据一致,但是,依旧有两个弊端:

  • 写操作只能在master上;
  • 如果master宕机,需要人为选择新主并重新给其他的slave端执行change master;

为了解决一系列问题,官方推出了MySQL Group Replication,从group replication发布以后,就有3种方法来实现MySQL的高可用集群:

  • 异步复制
  • 半同步复制
  • group replication

 

三、Group Replication原理

      MySQL Group Replication有两种模式,单主模式single-primary mode和多主模式multi-primary mode,在同一个group内,不允许两种模式同时存在,并且若要切换到不同模式,必须修改配置后重新启动集群。

1、单主模式

在单主模式下,只有一个节点可以读写,其他节点提供只读服务。单主模式下,该参数 _ 必须被设置为 FALSE ,当主节点宕掉,自动会根据服务器的server_uuid变量和group_replication_member_weight变量值,选择下一个slave谁作为主节点,group_replication_member_weight的值最高的成员被选为新的主节点,该参数默认为50,建议可以在节点上设置不同值;在group_replication_member_weight值相同的情况下,group根据数据字典中 server_uuid排序,排序在最前的被选择为主节点。

  • 单主模式中发现当前的主服务器,该值VARIABLE_VALUE为实例节点的server_uuid:

select * from performance_schema.global_status WHERE VARIABLE_NAME like '%group_replication%';

四、简单查询

# 开启单主模式
mysql> set global group_replication_single_primary_mode=on;
Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)

# 设置使用组复制的用户
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.07 sec)

mysql> start group_replication;
Query OK, 0 rows affected, 1 warning (2.08 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)



mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 1fa7b3ca-9475-11e8-a217-5254004e7cfe | 172.17.0.48 |        3306 | ONLINE       |
| group_replication_applier | 81d824f1-90ba-11e8-a83d-52540043d75a | 172.17.0.2  |        3306 | ONLINE       |
| group_replication_applier | b13df29e-90b6-11e8-8d1b-525400fc3993 | 172.17.0.37 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)

mysql> show variables like '%read_on%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | OFF   |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
| tx_read_only          | OFF   |
+-----------------------+-------+
5 rows in set (0.00 sec)


mysql> show variables like '%server_uuid%';
+---------------+--------------------------------------+
| Variable_name | Value                                |
+---------------+--------------------------------------+
| server_uuid   | b13df29e-90b6-11e8-8d1b-525400fc3993 |
+---------------+--------------------------------------+
1 row in set (0.00 sec)

mysql> select * from performance_schema.global_status WHERE VARIABLE_NAME like '%group_replication%';
+----------------------------------+--------------------------------------+
| VARIABLE_NAME                    | VARIABLE_VALUE                       |
+----------------------------------+--------------------------------------+
| group_replication_primary_member | b13df29e-90b6-11e8-8d1b-525400fc3993 |
+----------------------------------+--------------------------------------+
1 row in set (0.01 sec)

mysql> show variables like '%group_replication_member_weight%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| group_replication_member_weight | 80    |
+---------------------------------+-------+
1 row in set (0.00 sec)

1、登录到数据库

mysql > mysql -uroot -pyourpassword  

2、关闭二进制日志记录功能

mysql > set sql_log_bin=0;  

3、创建一个用于复制的用户,不建议用root用户

mysql > grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';  

mysql > flush privileges;  

4、开启二进制日志记录功能

mysql > set sql_sql_log_bin = 1;  

5、 设置使用组复制的用户

mysql > change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';  

6、安装组复制插件

mysql > install PLUGIN group_replication SONAME 'group_replication.so';  

7、开启插件自动引用组功能

mysql > set global group_replication_bootstrap_group = ON;  

8、 开启组复制

mysql > start group_replication;  

9、关闭插件自动引用组功能

mysql > set global group_replication_bootstrap_group = OFF;  

10、查看组内节点和节点状态

查看组内成员

mysql> select * from performance_schema.replication_group_members; 
+---------------------------+--------------------------------------+----------------------------------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST                            | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+----------------------------------------+-------------+--------------+
| group_replication_applier | 5d5b3ceb-9cdc-11ea-a3f6-0242ac11000e | mysql-cluster-0.mysql-cluster-gvr.test |        3306 | ONLINE       |
| group_replication_applier | 70f1b749-9cdc-11ea-b2a7-0242ac11000f | mysql-cluster-1.mysql-cluster-gvr.test |        3306 | ONLINE       |
+---------------------------+--------------------------------------+----------------------------------------+-------------+--------------+
2 rows in set (0.01 sec)
  • CHANNEL_NAME : 显示的值永远为group_replication_applier

  • MEMBER_ID : 节点serer_uuid

  • MEMBER_PORT : 节点服务端口,取值为server_port指定的端口

  • MEMBER_HOST : 如果没有配置report_host选项,那么取值为机器的hostname,可以通过report_host配置指定具体的IP

  • MEMBER_STATE : 节点状态

  • MEMBER_STATE字段显示当前节点的状态,根据官方文档,取值和介绍如下所示:

取值 解释 状态是否在集群内同步
ONLINE 表示该节点可正常提供服务 YES
RECOVERING 表示当前节点正在从其他节点恢复数据 YES
OFFLINE 表示GR插件已经加载,但是该节点不属于任何一个GR组 NO
ERROR 表示节点在recovery阶段出现错误或者从其他节点同步状态中出现错误 NO
UNREACHABLE 节点处于不可达状态,无法与之发生网络通讯 NO

从上表可以知道,只有ONLINERECOVERING两种状态会在集群中得到同步。这个状态同步是指状态在所有节点上面查询均能保持一致的意思。至于OFFLINEERRORUNREABLE,做以下说明:

  • 只有在当前OFFLINE节点查询replication_group_members表才能得到OFFLINE状态,在其他节点上查询replication_group_members表,则一般没有该节点的状态(很好理解,因为OFFLINE节点已经不属于这个GR组了)
  • 只有在当前ERROR节点查询replication_group_members表才能得到ERROR状态,同上面的OFFLINE,在其他节点上查询也看不到该节点
  • 假设节点A与B网络通讯失败,那么在节点A上查询replication_group_members表,有可能得到B的状态为UNREACHABLE

五、题外话(MGR的限制)

  • 仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测;

  • 必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set

  • COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景

  • 目前一个MGR集群最多支持9个节点

  • 不支持外键于save point特性,无法做全局间的约束检测与部分部分回滚

  • 二进制日志不支持binlog event checksum

 

六、参考资料

参考文章1:https://yq.aliyun.com/articles/702208

参考文章2:https://www.jianshu.com/p/cbe3ba27295c

参考文章3:https://database.51cto.com/art/202004/615706.htm?mobile

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章