深坑!!!请注意!在Mysql group replication发现的”丢失数据”的场景

栏目: 数据库 · 发布时间: 7年前

内容简介:深坑!!!请注意!在Mysql group replication发现的”丢失数据”的场景

之所以想使用基于paxos协议的group replication,目的是为了更好的保障数据库的数据安全,包括数据一致性以及数据零丢失。目前虽然采用半同步,可以保障数据的安全,但在极端情况下,出现数据库主从误切的时候,出现老主库跟新主库同时都有写入的场景时,就破坏了数据一致性。为了避免这个状况,基于paxos协议支持多节点写入的技术开始在 mysql 各种版本上使用。  mysql官方也采用的group replicaiton 插件来实现这个功能。

在进行group replication的测试过程中,惊奇地发现以下现象:

特别说明一下,group replication的模式为single primary。 因为一些原因,导致原来primary节点被驱逐,集群内部重新选举了新的primary 节点, 切换之后不再有 sql 操作。

新primary节点的gtid 如下:

gtid_executed                                     | aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-9578875,
d5e35917-4cde-11e7-9791-1c98ec1cbc64:1-6

原来的primary节点重起之后,查看一下其gtid的信息。

gtid_executed                                     | aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-9578876,
d5e35917-4cde-11e7-9791-1c98ec1cbc64:1-6 
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-9578876 比
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-9578875 多一个事务。 也就是老的primary节点比新的primary节点多了一个事务? 为什么有最后1个事务没有传送到新的主库?  原因作者目前也不知道。 我们来看一下最后一个事务是什么事务:
# at 626
#170612 11:03:20 server id 128283359  end_log_pos 687   GTID    last_committed=1        sequence_number=2
SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:9578876'/*!*/;
# at 687
#170612 11:03:20 server id 128283359  end_log_pos 746   Query   thread_id=6     exec_time=499   error_code=0
SET TIMESTAMP=1497236600/*!*/;
BEGIN
/*!*/;
# at 746
#170612 11:03:20 server id 128283359  end_log_pos 925 View_change_log_event: view_id=14972366013867880:2
# at 925
#170612 11:03:20 server id 128283359  end_log_pos 990   Query   thread_id=6     exec_time=499   error_code=0
SET TIMESTAMP=1497236600/*!*/;
COMMIT
/*!*/;
我们看到,是一个view change 事件产生的gtid, view change发生在group replication组内节点的加入或者离去的过程中。因此,这个丢失的事务,不是一个业务sql产生的事务。 因此,新主库没有丢失数据。 但是,这是否就没有问题了?继续看后面的内容。 

现在我们试图把原来的primary节点加入到group replication复制组中去, 执行start  group_replication命令,但该命令会提示错误。查看错误日志文件,得到的信息如下:

2017-06-12T11:09:54.263840+08:00 0 [Note] Plugin group_replication reported: 'A new primary was elected, enabled conflict detection until the new primary applies all relay logs'
2017-06-12T11:09:54.263936+08:00 0 [ERROR] Plugin group_replication reported: 'This member has more executed transactions than those present in the group. Local transactions: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-9578876,
d5e35917-4cde-11e7-9791-1c98ec1cbc64:1-6 > Group transactions: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-9578875,
d5e35917-4cde-11e7-9791-1c98ec1cbc64:1-6'2017-06-12T11:09:54.263980+08:00 0 [ERROR] Plugin group_replication reported: 'The member contains transactions not present in the group. The member will now exit the group.'

错误日志 中输出的信息表达得很清楚,就是准备加进来的节点执行的事务比组内的事务还多, 拒绝加入

但dba很多时候,“往往不信邪”,第一次执行失败之后,会尝试第二次(作者当时也是如此)。 但是,执行第二次的,却 “妥妥滴”成功了真的是妥妥的吗? 为什么第二次却可以是成功的呢?原因是因为: 执行第一次start group_replication的时候, 因为有view change 事务产生,primary节点的

gtid_executed将增加1个事物,所以新旧primary节点的gtid_executed就完全相等了 ,所以第二次启动的时候不再抱错。 但问题就解决了吗?

假如在新的primary上执行一个业务的sql,使其gtid_excuted增加1, 然后再将老的primary节点加入组复制,结果会是怎么?

我们继续进行试验,实验场景一样,老primary节点的gtid_executed比新的primary 节点gtid_executed多一个事务,但这次我们是先在新的primary节点上执行一个sql,然后再将老的primary节点加入group replication组复制。

此时,我们在新的主库执行一个事务: mysql> select * from xcy_test;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    1 |
| 3 |    1 |
+---+------+
3 rows in set (0.00 sec)

mysql> insert into   xcy_test values(4,5);
Query OK, 1 row affected (0.01 sec)

mysql> select * from xcy_test;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    1 |
| 3 |    1 |
| 4 |    5 |
+---+------+
4 rows in set (0.00 sec)

然后在老的primary节点上执行start group_replication 加入复制组,命令没有报错。然后在该节点上查询刚刚插入的记录。 刚刚被插入的数据被没有复制到该节点,数据丢失。好恐怖。。。。

mysql> start group_replication;
Query OK, 0 rows affected (2.16 sec)

mysql> select * from xcy_test;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    1 |
| 3 |    1 |
+---+------+
3 rows in set (0.00 sec)

在作者的暴力测试中,居然发现新的primary节点的执行的事务数比老的primary节点的事务数少,而少的这个事务目前发现是发生选举新主库时产生的view change 事务,虽然不造成新primary丢失业务数据, 但是当老primary再次加入组复制时,该节点将可能丢失数据,不再是一个完整的复制副本

组复制的逻辑还是比较复杂,细节也非常多,目前尚未弄清出现这种状况的原因,后续期待大牛跟官方能够提供支持,确认是否是bug?

但测试过程中出现现象也同样值得我们敬畏 。 首先抛开该问题是否是bug,是否可以采用合理的操作步骤来避免这些观念, 仅仅从测试过程出现的现象本身来看,至少可以确认的一点是: “group replication虽然是为了解决主从数据一致性而生,但是,并不代表它完全不会带来破坏数据一致性的缺陷,在这个方面依然需要关注,谨慎甚至敬畏“  。 从作者的测试过程中发现,排除数据库可能存在的bug, 在隐含的不正确的场景下,进行了看似合理的操作,也将可能引发产生主从数据不一致的现象。   正是因为这些现象, 刷新了作者之前的关注点 ——因为group replication目的就是为了解决数据一致性而引进的,之前的关注点都在它因为有新功能而引进了哪些其他方面的限制。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

常用算法程序集

常用算法程序集

清华大学出版社 / 2013-4 / 69.00元

《常用算法程序集(C\C++描述第5版清华大学计算机系列教材)》编著者徐士良、马尔妮。 《常用算法程序集(C\C++描述第5版清华大学计算机系列教材)》是针对工程中常用的行之有效的算法而编写的,主要内容包括多项式的计算、复数运算、随机数的产生、矩阵运算、矩阵特征值与特征向量的计算、线性代数方程组的求解、非线性方程与方程组的求解、插值与逼近、数值积分、常微分方程组的求解、数据处理、极值......一起来看看 《常用算法程序集》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具