本文来自数据库内核专栏

在之前的文章中,介绍了MGR对数据可靠性、可用性和一致性的实现方案。简单来说,MGR通过基于paxos协议的多副本来实现数据的可靠性,通过多副本上的majority机制来实现可用性。对于一致性,主要说的是多主模式下通过基于事务版本的认证机制来确保多节点并发更新的正确性。

本文再介绍下MGR对于数据安全性的保护,这里所说的安全性是指MGR中的数据不会被外来的操作所影响,从而引起不同节点的数据处于不一致的状态,由于引起不一致的原因是外来的、计划外的,所以归为安全性的范畴。

一,先说说单主模式下Secondary节点的安全性保障。该模式下,MGR会将Secondary节点的super_read_only设置为true来确保Secondary节点无法处理写事务。这是因为,虽然是MGR对外呈现是单主模式,但Xcom层的Paxos还是多点可写,也就是说Secondary节点的Paxos仍可以作为proposer。在这种情况下,如果不将super_read_only设置为true,那么在没有事务认证机制参与的情况下,不同节点的事务就可能因为冲突导致数据状态出错。因此,Secondary节点在执行start group_replication操作时super_read_only被置为true。

mysql 查询保证数据唯一性 mysql保证数据安全的方法_MySQL复制怎么保证数据安全

图中所示为一个节点作为Secondary加入MGR前后super_read_only变化情况。

二、除了在加入(start group_replication)MGR集群时会设置super_read_only,在退出MGR集群时也会设置它,不管是主动退出(stop group_replication)还是异常退出(比如网络分区等原因)。这是一种预防性措施,避免节点退出集群后数据被意外修改掉。节点在加入集群时,集群会检查节点的数据版本信息、如果节点的数据版本中存在集群没有的数据,那么集群会拒绝该节点加入其中,因为这意味着该节点的数据跟集群数据不一致。所以,MGR在节点退出时主动将其super_read_only设置为true,用户需要手动将其设置为false才能进行写操作,最大限度减低因为误操作导致节点数据被意外更改。

mysql 查询保证数据唯一性 mysql保证数据安全的方法_数据库_02

图中所示为primary节点退出MGR前后的super_read_only变化,可以发现退出后只读开启,手动关闭只读新建一个数据库后重新加入集群,提示3092错误。错误日志如下:

mysql 查询保证数据唯一性 mysql保证数据安全的方法_再启动_03

三、除了上面所述节点加入或退出MGR时需要设置正确的super_read_only值外,还需要保证MGR节点不受异步复制通道影响。这又可以分为4种情况。

1、需防止单主模式Secondary节点写入异步复制通道数据。也就是说一个节点不能同时是MGR集群的Secondary节点和Master-Slave复制(广义的异步复制,包括半同步复制)的Slave节点。这是因为,Secondary节点会回放Primary节点的事务,如果又同时接收和回放另一个复制通道的Master节点事务,这意味着该节点的数据跟其他MGR节点不一致,可能引起数据冲突等多种严重问题,这显然是不可接受的。

mysql 查询保证数据唯一性 mysql保证数据安全的方法_MySQL复制怎么保证数据安全_04

所以,既不能将异步复制的Slave节点作为单主模式Secondary节点,也不能在单主模式Secondary节点上再启动异步复制Slave节点;

2、不同于第1点,单主模式的Primary节点以及多主模式下,节点可以作为异步复制的Slave节点。但在节点写入异步复制通道数据前,需要检查数据是否符合MGR约束,包括必须为InnoDB表,需显式定义主键,没有CASCADE外键等;

mysql 查询保证数据唯一性 mysql保证数据安全的方法_数据库_05

3、上面已经提到节点退出MGR时super_read_only会设置为true,但这无法阻塞relay-log中事务的回放,如果该节点上有异步复制通道,那么该节点还会有原因不断的数据更新,而退出集群后更新的数据对集群的其他节点是不可见的,这显然也是无法被接受,因此,在节点退出MGR集群时,其上的异步复制通道也会被停止。

mysql 查询保证数据唯一性 mysql保证数据安全的方法_再启动_06

4、最后,若配置mysqld重启后自动启动MGR和异步复制通道,需要确保启动顺序协调一致。原则是确保MGR应该先于异步复制通道启动,MGR节点变为ONLINE状态后再启动异步复制通道。主要考虑三点:a、先确保MGR在线,再启动异步复制;b、如果MGR启动失败,那么异步复制也必须返回失败;c、如果在单主模式Secondary节点上配置了自动启动,那么需要保证MGR启动成功,异步复制返回失败。

最后介绍下InnoSQL在这方面的增强。InnoSQL增加了一个参数group_replication_readonly_after_reconfig,该参数与官方提供的group_replication_force_members配合使用。当MGR集群因为异常导致只有一个节点在线时,由于失去majority导致该节点会阻塞写事务的提交,group_replication_force_members参数可以通过重配置,让MGR集群成为只有该节点的新集群,从而能够正常执行写事务。但正因为此时集群中只有一个节点,写入的数据是极不可靠的。

对于RDS云服务中3节点的MGR金融版实例,2个节点下线后,存活的节点本就应该只提供读服务。若因为配置group_replication_force_members导致系统变为可写状态,这显然是不合适的。group_replication_readonly_after_reconfig就是为了控制group_replication_force_members后节点的读写行为,如果启用,那么重配置后,节点会变为只读状态,在实现上也是通过设置super_read_only为true实现。

网易云数据库RDS是一种稳定可靠、可弹性伸缩的在线关系型数据库服务,当前支持MySQL引擎,提供基础版,高可用版,金融版针对不同业务场景的高可用解决方案,同时提供多重安全防护措施,性能监控体系,专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。