vlambda博客
学习文章列表

MySQL|别拿MySQL半同步忽悠数据强一致性

加关注哦


经常听到有人说基于MySQL的主从复制技术实现了数据的强一致性,听的多了,我开始怀疑是不是自己之前的知识错的,因此又细致的看了一下MySQL的文档并进行了实验,证明了自己之前到的理论是正确的。这也说明了我知识掌握的不扎实。



经常听到有人说基于MySQL的主从复制技术实现了数据的强一致性,听的多了,我开始怀疑是不是自己之前的知识错的,因此又细致的看了一下MySQL的文档并进行了实验,证明了自己之前到的理论是正确的。这也说明了我知识掌握的不扎实。


1. 官方文档分析

        参考MySQL 5.7[MySQL Reference Manual]的16.3.9章节半同步复制,对于同步是这样介绍的:

参考内容一:除了内置的异步复制,MySQL 5.7 还支持由插件实现的半同步复制接口。

        这也就说明了复制技术是MySQL自带的,且是属于异步复制,如果想进一步加强同步能力,需要借助插件,半同步就是其中的一个插件。

参考内容二:文档中提到完全同步的概念:当源提交事务时,所有副本也必须在源返回到执行事务的会话之前提交事务。完全同步复制意味着可以随时从源故障转移到任何副本。完全同步复制的缺点是完成事务可能会有很多延迟。

这里对于原文的概念需要理解三点。

  1. 源提交事务的前提是,所有副本均接受并提交事务。重点在提交事务上。

  2. 完全同步要满足的是所有同步副本均参与。也就是说如果复制架构中有异步副本,是不算在内的。

  3. 完全同步是能够满足可随时故障转移。重点是随时。

参考内容三:半同步复制介于异步复制和完全同步复制之间。源等待直到至少一个副本接收并记录了事件(所需的副本数量是可配置的),然后提交事务。源不等待所有副本确认接收,它只需要来自副本的确认,而不是事件已在副本端完全执行并提交。因此,半同步复制保证如果源崩溃,它已提交的所有事务都已传输到至少一个副本。

        半同步的概念是依据介于异步和全同步,且确认接收的副本个数是可控制的,这也是官方一致在宣称的其与异步和全同步的优势。

        这里也应该注意的一点是,半同步复制的实现是源不等待所有副本确认接收,只需要来自副本的确认,而不是事件已在副本端完全执行并提交。也就是从节点只是接收了事件的日志就反馈ack信号给主库,并未等待从库将事件应用到数据库中。


2. 实验校验

        这里只验证半同步复制在从库是否等待事件应用再反馈ACK信号。

        环境是一主一从,安装了半同步插件,并开启。这里暂不讨论AFTER_SYNCAFTER_COMMIT

+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_semi_sync_slave_enabled               | ON         |
+-------------------------------------------+------------+

        从库show slave status查看IO thread及SQL thread状态

             Slave_IO_Running: Yes
          Slave_SQL_Running: Yes

        要验证是否等待事件应用再反馈ACK信号,只需要将从库的SQL thread停掉,即Slave_SQL_Running变为NO

stop slave sql_thread;

        停掉SQL thread后,主库数据库日志没有发生任何变化。接下来再主库做一条DML,看会是什么结果,猜测:如果是在事件应用后反馈ACK,那么主库操作会卡顿,并等待一秒钟才能提交(rpl_semi_sync_master_timeout=1000)。如果不是在事件应用后,而是在日志接收后,那么会立即提交成功。

(root@localhost 22:04:00) [digops]>insert into t values(3);
Query OK, 1 row affected (0.04 sec)

0.04秒,是立即提交。


3. 什么是数据强一致性

        这里只针对主从复制这种架构而言,也就是MySQL官方文档所介绍的完全同步,只有在从库应用了事件后,主库才能提交,这样才能保证数据具有强一致性,这种同步是最时效的同步,也能够真正的保证数据的RPO=0。


4. 总结

        经过上两小节的验证,也印证了主从复制这种模式,实现完全同步的难度,半同步只是一种折中方案,但却并不具备强一致的能力,除非是改源码,将从库的ack确认在事件应用以后。那为什么官方没有这么做呢?其本质原因仍然是WAL日志的实现方式导致的,这在之前的文章中提到过。对于小事务来说,可以快速落盘及应用,但对于长事务来说,这是致命的,会严重影响生产业务的可用性和并发性。

        也并不是说MySQL不具备完全同步的能力,在5.7版本中新增了组复制的插件,其数据的一致性采用消息传递方式,但限制较多,因为这项功能是基于innodb存储引擎实现的。

        如果再有人将基于MySQL的半同步实现数据的强一致来对外宣传说教,真的要去甄别其用心了~