查看原文
其他

盘点几种MySQL复制的解决方案和常见的错误理解

程序猿DD 2020-10-16

The following article is from 阿飞的博客 Author 阿飞的博客

点击蓝色“程序猿DD”关注我

回复“资源”获取独家整理的学习资料!

作者 | 阿飞的博客

来源 | 公众号「阿飞的博客」

本文将回顾MySQL复制概念和MySQL几种复制方案,同时也会澄清一些关于复制问题的误解。

本文翻译自:https://www.percona.com/blog/2017/02/07/overview-of-different-mysql-replication-solutions/

MySQL复制是什么?

复制能够保护信息得到备份,并且备份会不同于原数据,备份会被保存到另一个环境。即主备数据不在同一台服务器。下图是MySQL复制示意图:

MySQL有哪些复制方案?

复制如此重要,那么在MySQL中我们有哪些选择呢?

1. 异步复制

异步复制意味着本地环境操作完成,事务就完成,不会受到slave复制是否完成的影响。

当改变被提交后,master就会把数据修改信息放到binlog中(也可能把实际的statement放到binlog中,这是row-based复制和statement-based复制的不同,后面会讲到)。dump线程读取binlog日志然后将其发送到slave,slave接受并保存到待处理队列中(被称为relay-log),slave会执行每一个在master上的改变:

2. 半同步复制

半同步复制(Semi-synchronous replication)意味着master和slave彼此通讯确保事务的正确转移。当改变发生时,master需要等待slave已经将日志保存到relay-log中并向master回复确认master才能提交事务。半同步复制可以保证事务被正确的复制,但不能保证在slave上一定发生:

需要注意的是,半同步复制的话,master需要等待至少有一个slave服务器确认接收到事务并保存了relay-log(或达到超时)才能继续处理同一个SESSION中的当前事务,至于具体多少个slave确认,可以通过参数rpl_semi_sync_master_wait_slave_count进行配置,这个值有效范围是1~1024之间,而且这个值可以动态更新。举个栗子:

假设rpl_semi_sync_master_wait_slave_count被设置为2,并且有两个slave,分别是:slave1和slave2。

\1. T1等待两个slave的ack;

\2. master收到slave1的ack;

\3. 此时加入一个slave3,并将rpl_semi_sync_master_wait_slave_count改为3;

\4. master收到slave2的ack;

\5. master收到slave3的ack;

\6. master唤醒等待中的事务,并准备提交;

记住半同步复制会影响性能,因为它需要等待来自slave的确认(ack)。但是,它也能减少slave上由于故障导致数据丢失的风险。

3. 组复制

组(Group)复制是MySQL5.7版本新介绍的概念,在5.7.17发布了GA,而且以插件模式提供。

任意一个数据库节点无论什么时候执行一个事务,组复制插件在向客户端响应它已经完成事务前,会尝试得到其他数据库节点的同意。组复制示意图如下:

4. Percona XtraDB Cluster / Galera Cluster

再介绍一个把master数据复制到其他节点的解决方案,就是Percona XtraDB Cluster,简称PXC。这个解决方案把重心放在一致性上,并且通过使用一个认证过程来保证事务避免冲突和执行的正确性。在这个集群方案的数据库环境下,每个节点的数据都是相同的,节点之间会依赖galera提供的广播机制来保证一致性。

以一条SQL为例,某节点接收SQL请求后,在commit之前,由wsrep API 调用galera库进行集群内广播,所有其他节点验证成功后事务在集群所有节点进行提交,反之rollback。PXC保证整个集群所有数据的强一致性,满足CAP理论中的CA,即 Consistency 和 Availability。

Percona XtraDB Cluster 有很多组件:

  • Percona Server for MySQL(MySQL的Percona分支);

  • Percona XtraBackup (主要用于集群的快照备份);

  • wsrep patches / Galera Library;

该解决方案几乎是同步的,可与组复制相媲美。但是,它还具有使用多主复制的能力。Percona XtraDB Cluster这样的组件能很好的提高数据库基础架构可用性:

Row-Based VS. Statement-Based

讨论MySQL复制,就不得不提Row-Based复制和Statement-Based复制。因为它们是两种不同复制方案的实现原理。

对于statement-based复制(被翻译为基于语句复制),执行的SQL本身会被写入binlog中,例如完全相同的INSERT/UPDATE/DELETE语句会被在slave上执行。它的优缺点如下:

  • 审计数据库会更容易,因为实际执行的SQL语句就被记录在binlog中;

  • 主从之间会有更少的数据传输;

  • binlog日志需要的空间更小;

  • 不确定性SQL可能会给slave带来很大的影响;

  • 某些操作(例如insert...select)会有性能劣势;

  • Statement-based复制会由于SQL优化和执行变得更慢;

  • slave上一些复杂SQL执行时,执行计划评估可能变得糟糕;

  • 数据一致性问题会有更大的挑战;

Row-based复制(基于行复制)是从MySQL 5.7.7起默认的选择,它有很多优点,改变的行会被记录在binlog中,因此它不需要上下文信息。它的其他优点如下::
  • 每一个改变都能被复制,所以是最安全的复制方式;

  • 对于包含不是很多行改变的高并发操作,性能有一定的提升;

  • 显著的改善了数据一致性;

当然,也有缺点:

  • 网络流量显著变大,尤其当操作很多行记录的时候,可能打爆网络;

  • 对于影响很多行的操作,Row-based就会很吃力,不擅长;

  • 数据库操作审计变得更加困难,因为binlog中不记录SQL,取而代之的是记录变更的数据;

  • Row-based相比statement-based在一些场景下会更慢;

关于复制的误解

误解1: 复制就是集群

标准的异步复制不是集群,记住不管是标准的异步复制还是半同步复制,都不能保证环境服务于同一数据集。而使用集群(例如Percona XtraDB Cluster)时,这是不同的,任意一个请求打到任意一台服务器上其结果都一样。如果不是,则会从群集中删除受影响的节点。异步复制没有这样的保障,即使某个slave节点与master处于不一致状态时仍然会接受操作请求。

误解2: 复制作为手动故障转移方案

理论上来说,两个环境之间是有可比性的。然而,有许多参数能影响性能和数据一致性。只要你使用了异步复制,在master上发生的事务正确性就无法在slave上得到保障。当然,你可以通过增强持久化的配置来改善这点,但是它相应的会带来一定的性能损耗,性能和可靠之间总需要做一定的取舍。

误解3: 我有复制,所以不用备份

复制是为了对数据集有一个可访问的副本的解决方案,通过把读请求打到复制节点,能减轻master的压力。但是复制不是备份。备份一般是指离线备份,它的作用是数据库所在环境发生灾难性的破坏不可恢复时,还能通过备份恢复数据库。对数据库进行离线备份是非常重要和有意义的事情!

误解4: 因为有复制,所以数据库能负载均衡事务请求

给master增加一个slave尽管可以改善系统的可用性,但是你仍然需要自己做几件事情:把读请求打到slave上,把写请求打到master上。有很多代理工具可以完成这样的事情,当然你可以自己动手造轮子!


本文通过OpenWrite的免费Markdown转换工具发布

-END-


留言交流不过瘾

关注我,回复“加群”加入各种主题讨论群




点一点“阅读原文”小惊喜在等你

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存