我在解决方案团队工作多年,发现数据库复制总是被误解,甚至有些人根本完全不理解,所以本文将来回顾一下MySQL环境中的复制概念,并且澄清一些大家对于复制的误解。

 

什么是复制?

复制:保证信息被复制并有目的地填充到另一个环境中,而不是仅存储在一个位置(基于源环境的事务)。如果更白话一点来说就是在您的基础架构上使用辅助服务器来读取或使用其他管理解决方案。

下图展示了MySQL复制环境的示例。

关于不同的MySQL复制解决方案概述-LMLPHP

如果我们把范围缩小到MySQL中,那么在复制时我们有几种选择呢?

标准异步复制

异步复制意味着事务完全在本地环境中完成,并且不受复制从属本身的影响。完成更改后,主服务器将使用数据修改或实际语句(基于行的复制或基于语句的复制之间的差异会在之后讲)填充二进制日志。此转储线程读取二进制日志并将其发送到从IO线程。从站使用其IO线程将其置于自己的预处理队列(称为中继日志)中。从站使用SQL线程执行从站数据库上的每个更改。

关于不同的MySQL复制解决方案概述-LMLPHP

半同步复制

半同步复制意味着从设备和主设备相互通信以保证事务的正确传输。主设备仅填充binlog并继续其会话,其中一个从设备确认事务已正确放置在从设备的中继日志中。

半同步复制可确保正确复制事务,但不保证实际发生从设备上的提交。

关于不同的MySQL复制解决方案概述-LMLPHP

需要注意的是,半同步复制可确保主服务器等待继续处理特定会话中的事务,直到至少有一个从服务器确认接收到事务(或达到超时)。这与异步复制不同,因为半同步允许额外的数据完整性。

请记住,半同步复制会影响性能,因为它需要等待来自从站的实际ACK的往返。

组复制

这是MySQL Community Edition 5.7中引入的新概念,并且在MySQL 5.7.17中进行了GA。这是一个用于虚拟同步复制的新插件。

每当在节点上执行事务时,插件都会尝试与其他节点达成共识,然后再将其返回给客户端。 虽然与标准MySQL复制相比,该解决方案是完全不同的概念,但它基于使用binlog生成和处理日志事件。

以下是组复制的示例体系结构。

关于不同的MySQL复制解决方案概述-LMLPHP

如果对Group Replication感兴趣,请参考以下文章:

http://mysqlhighavailability.com/mysql-group-replication-its-in-5-7-17-ga/

http://mysqlhighavailability.com/performance-evaluation-mysql-5-7-group-replication/

Percona XtraDB Cluster/ Galera Cluster

另一种允许将信息复制到其他节点的解决方案是Percona XtraDB Cluster。此解决方案侧重于提供一致性,使用认证过程来保证事务避免冲突并正确执行。在这种情况下,我们讨论的是集群解决方案,每个环境都受相同数据的约束,并且节点之间存在通信以保证一致性。

Percona XtraDB Cluster有多个组件:

Percona Server for MySQL

Percona XtraBackup用于执行正在运行的集群的快照(正在恢复或添加节点)。

wsrep patches/Galera Library

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

关于不同的MySQL复制解决方案概述-LMLPHP

基于行的复制与基于语句的复制

使用基于语句的复制,SQL查询本身将写入二进制日志。例如,从站执行完全相同的INSERT / UPDATE / DELETE语句。

该方法有很多优缺点:

由于实际语句记录在二进制日志中,因此审核数据库要容易得多

通过线路传输的数据更少

非确定性查询可能会在从属环境中造成实际破坏

某些查询存在性能劣势,例如基于SELECT的INSERT

由于SQL优化和执行,基于语句的复制速度较慢

基于行的复制是自MySQL 5.7.7以来的默认选择,具有许多优点。行更改记录在二进制日志中,并且不需要上下文信息,消除了非确定性查询的影响。

其它优点包括:

包含少量行更改的高并发查询的性能改进

显着的数据一致性改进

其缺点包括:

如果有修改大量行的查询,那么网络流量可能会大得多

审核数据库的更改更加困难

在某些情况下,基于行的复制可能比基于语句的复制慢

关于复制的误解

复制是集群

标准异步复制不是同步集群。请记住,标准和半同步复制不保证环境服务于同一数据集。使用Percona XtraDB Cluster时,每个服务器实际上需要分别处理每个更改。如果不是,则从群集中删除受影响的节点。异步复制不具有此故障安全性,在不一致的情况下,仍然可以接受读操作。

从理论上讲,环境应具有可比性。但是,有许多参数会影响数据传输的效率和一致性。只要使用异步复制,就无法保证事务正确发生。使用者可以通过增强配置的持久性来避免这种情况,但这会带来性能损失。

使用pt - table - checksum工具验证主服务器和从服务器的一致性 。

有复制就不需要备份了

没错,复制是一个很好的解决方案,可以获得数据集的可访问副本(例如报告问题,读取查询,生成备份)。但其并不能替代备份解决方案。通过异地备份,可以在发生重大灾难、用户错误或其他原因时可以重建环境。有些人使用 delayed slaves ,但它也不能取代适当的灾难恢复程序。

有复制,所以环境将负载平衡事务

虽然通过使用相同数据集运行辅助实例可能会提高环境的可用性,但仍可能需要将读取查询指向从属服务器,而将写查询指向主服务器。你可以使用代理工具或在自己的应用程序中定义此功能。

复制会显着减慢速度

复制对主服务器的性能影响很小。 Peter Zaitsev在一篇文章中曾讨论过从服务器对主服务器的潜在影响。请记住,写入二进制日志可能会影响性能,尤其是当您有许多小事务,然后被多个从服务器转储和接收时。

当然,除此之外还有许多其他参数都可能会影响实际主从设置的性能。

最后送波福利。现在加群即可获取Java工程化、高性能及分布式、高性能、高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点高级进阶干货的直播免费学习权限及领取相关资料,群号:835638062 点击链接加入群聊【Java高级架构】:https://jq.qq.com/?_wv=1027&k=5S3kL3v

10-06 21:42