数据生态:MySQL复制技术与生产实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

基础篇

第1章 复制的概述

简单来说,“复制”就是将来自一个MySQL Server(这里指master角色,即主库)的数据变更,通过其逻辑的二进制日志(binlog)传输到其他的一个或多个MySQL Server(这里指slave角色,即从库)中,其他MySQL Server通过应用(回放)这些逻辑的二进制日志来完成数据的同步。这些MySQL Server之间的逻辑关系,我们称为“复制拓扑”(也可以称为“复制架构”)。

默认情况下,复制是异步的,即主库将二进制日志传输到从库之后,并不关心从库是否成功收到。从库是否收到这些二进制日志,不影响主库的任何读/写访问;而从库的复制线程也可以随意暂停或停止,并不影响主库的读/写访问。通常,异步模式能够发挥数据库的最高性能,但数据安全性却得不到很好的保证,如果对数据安全性的要求较高,可以考虑使用半同步复制。

另外,默认情况下,复制的数据是针对整个实例的(排除部分系统表),你可以根据自身需求选择是否需要复制整个实例的数据,是只复制某些库,还是只复制某些表的数据等。接下来将简要介绍MySQL中复制拓扑的一些适用场景,以及与复制相关的概念。

1.1 适用场景

MySQL主从复制拓扑可用于如下场景:

1. 横向扩展(Scale-Out)

横向扩展是指在多个从库之间进行读负载均衡,以提高读性能。在此扩展方案中,所有数据变更在主库上执行,读负载可以分摊到一个或者多个从库上。可以把之前在主库上的读负载剥离出来,以承载更多的写请求,另外,如果读负载越来越大,可以通过扩展从库来提高读性能。

2. 数据安全性(Data Security)

数据安全性在很大程度上需要靠数据副本来保证。在这里,副本可以理解为我们通常所说的备份。在MySQL中,为了保证二进制日志的位置和数据的一致性,通常在执行备份时需要阻塞写操作,防止因数据变更而造成备份过程中所获取的二进制日志位置与数据不一致。

大多数时候,我们使用的MySQL主从复制拓扑是这样的:一主N从、两主N从(N大于或等于1)。其中,主库提供读与写或者只写服务,从库提供只读服务(多个从库通常会提供读负载均衡以分摊单个从库的读压力)。而主库通常只有一个(在有两个主库的复制拓扑中,另一个主库通常用于提供快速的高可用切换),提供只读服务的从库通常有多个。因此,虽然在主库上执行备份能够尽可能保证备份数据的实时性(即拥有最新的数据),但是由于在备份过程中需要通过阻塞写操作来保证数据的一致性,因此会严重影响应用的写可用性。对于主库来说,从库有多个,所以如果在从库上执行备份,对只读应用的可用性影响就要小很多(从库的复制机制本身也支持断点续传)。也就是说,在执行备份操作时,选择使用从库而不使用主库是一个更好的替代方案,这样可以尽量减少对主库性能以及数据安全性的影响。

3. 分析(Analytics)

在主库上运行OLTP(联机事务处理)应用,而OLAP(联机分析处理)应用可以在从库上运行,避免在主库上运行OLAP应用对主库性能造成影响。

4. 远程数据分发(Long-Distance Data Distribution)

可以使用复制特性为远程站点(例如分公司或者分地域的应用中心)创建数据的本地副本,那些对数据实时性没有要求的应用可以访问本地副本,剩下的一小部分对实时性有要求的应用访问主库。远程站点既可以作为灾备中心,也可以用于实现跨地域访问以分摊负载,以及实现就近访问,加快访问速度。

5. 在线滚动升级(Online Rolling Upgrade)

先升级从库,然后执行主从切换,再升级主库,从而实现数据库应用不停机的在线升级(这里说的“不停机”并不是指应用完全无感知,在执行主从切换时,应用需要重新连接数据库)。

6. 高可用切换(Failover)

当主库发生故障时,可以把从库提升为主库,从而快速恢复服务。

1.2 数据同步方法

MySQL 5.7支持以下两种数据同步方法(也可以称为复制模式或复制方法):

• 传统复制:也可以称为基于二进制日志文件和位置的复制,在从库中配置复制时,要求指定从主库中获取的二进制日志文件(binlog file)和位置(binlog position),以便从库中的复制线程启动时,能够以指定的二进制日志文件和位置为起点,持续读取主库中的二进制日志,并在从库中应用,从而达到数据同步的目的。

• 基于GTID的复制(本书中为了表述上的方便,简称为GTID复制):GTID(全局事务标识符)是新的事务性复制方法,利用GTID可以自动在主库中寻找需要复制的二进制日志记录,因此不需要关心日志文件或位置,极大地简化了许多常见的复制任务。使用GTID复制可确保主库和从库之间的一致性。有关GTID的更多细节,详见4.2节“GTID复制”。

1.3 数据同步类型

MySQL支持如下4种不同类型的数据同步:

• 异步复制:是最早出现的复制技术,MySQL内置支持,不需要额外安装插件。其中,一个实例充当主库,一个或多个其他实例充当从库,与同步复制形成对比。

• 半同步复制:MySQL 5.7(从MySQL 5.5开始支持半同步复制)除内置了异步复制之外,还支持半同步复制。使用半同步复制时,主库的会话在提交事务之前,会等待至少一个从库返回收到二进制日志的ACK消息(确认接收,并将事务的事件记录到从库的中继日志中)。

• 延迟复制:MySQL 5.7还支持延迟复制(从MySQL 5.6开始支持),使得从库可以故意滞后于主库至少一段指定的时间,以便在出现误操作时,有时间对误操作的数据进行补救。

• 同步复制:指的是需要保证写操作完全同步到其他数据节点,而不仅仅是二进制日志被其他节点接收。例如NDB Cluster,它是一种集群架构,所有节点都可以进行读/写,而且每个节点上发生的写操作都会实时同步到其他节点。对于需要同步复制的场景,可以使用NDB Cluster,或者其他类似的开源解决方案(虚拟同步,非完全同步),例如Percona XtraDB Cluster(PXC)、MariaDB Galera Cluster(MGC)、MySQL Group Replication(MGR)。

1.4 复制格式

MySQL支持两种二进制日志格式(二进制日志记录的是数据变更的逻辑):一种是记录语句原始文本(即statement格式,语句文本按原样记录到二进制日志),另一种是记录数据的逐行变更(即row格式,将一个语句记录到二进制日志中,可能产生多行数据变更记录)。就具体的复制格式而言,可以分为三种,由系统变量binlog_format进行设置,有效值为:statement(对应下文中的SBR)、row(对应下文中的RBR)、mixed(mixed格式,混合使用statement和row格式,对应下文中的MBR)。这三种格式的详情如下:

• 基于statement的复制(Statement Based Replication,SBR):当系统变量binlog_format设置为statement时表示使用SBR。SBR复制的是整个SQL语句的原始文本,日志量较小,但容易出现主从库数据不一致。对于SBR,当执行的某个语句被判定为不安全时,是否允许其执行还取决于事务的隔离级别。

• 基于row的复制(Row Based Replication,RBR):当系统变量binlog_format设置为row时表示使用RBR。RBR复制的是发生更改的数据行的实际记录(原始语句会被转换为发生变更的行数据记录),日志量较大,但可以保证主从库数据的一致性。

• 混合复制(Mixed Based Replication,MBR):系统变量binlog_format设置为mixed时表示使用MBR。MBR实际上是由MySQL自行判断的,即在不影响数据一致性的情况下,使用SBR;如果可能影响数据一致性,则自动转换为RBR。

提示:本章中复制相关的概念较多,容易混淆,这里做一个总结。MySQL中的复制,按照数据同步方法划分,可分为传统复制和GTID复制;按照数据同步类型划分,可分为异步复制、半同步复制、延迟复制和同步复制;按照复制格式划分,可分为基于statement的复制(SBR)、基于row的复制(RBR)和混合复制(MBR)。

有关复制的格式的更多信息,详见第3章“复制格式详解”。