王尘宇王尘宇

研究百度干SEO做推广变成一个被互联网搞的人

MySQL实战宝典 高可用架构篇 15 MySQL 复制:最简单也最容易配置出错


MySQL 数据库的复制架构

在MySQL复制中,一台数据库服务器的角色是Master,剩下的服务器角色均为Slave:

  • Master服务器会把数据变更产生的二进制日志通过Dump线程发送个Slave服务器
  • Slave服务器中的I/O线程负责接收二进制日志,并保存为中继日志
  • SQL/Worker线程负责并行执行中继日志,即在Slave服务器上回放Master产生的日志

得益于二进制日志,MySQL的复制相比其他关系型数据库,如Oracle、PostgreDB等,非常灵活,用户可以根据自己的需要购机所需的复制拓扑结构,比如:

复制拓扑结构

在上图中,Slave1、Slave2、Slave3 都是 Master 的从服务器,而 Slave11 是 Slave1 的从服务器,Slave1 服务器既是 Master 的从机,又是 Slave11 的主机,所以 Slave1 是个级联的从机。同理,Slave3 也是台级联的从机。

在了解完复制的基本概念后,我们继续看如何配置 MySQL 的复制吧。

MySQL复制配置

搭建 MySQL 复制实现非常简单,基本步骤如下:

  1. 创建复制所需的账号和权限;

  2. 从 Master 服务器拷贝一份数据,可以使用逻辑备份工具 mysqldump、mysqlpump,或物理备份工具 Clone Plugin;

  3. 通过命令 CHANGE MASTER TO 搭建复制关系;

  4. 通过命令 SHOW SLAVE STATUS 观察复制状态。

虽然 MySQL 复制原理和实施非常简单,但在配置时却容易出错,请你务必在配置文件中设置如下配置:

gtid_mode = on
enforce_gtid_consistency = 1
binlog_gtid_simple_recovery = 1
relay_log_recovery = ON
master_info_repository = TABLE 
relay_log_info_repository = TABLE

上述设置都是用于保证 crash safe,即无论 Master 还是 Slave 宕机,当它们恢复后,连上主机后,主从数据依然一致,不会产生任何不一致的题。

请确认上述参数都已配置,否则任何的不一致都不是 MySQL 的问题,而是你使用 MySQL 的错误姿势所致。

了解完复制的配置后,我们接下来看一下 MySQL 支持的复制类型。

MySQL复制类型及应用选项

MySQL 复制可以分为以下几种类型:

MySQL 复制类型

异步复制

在异步复制(async replication)中,Master不用关心Slave是否接收到二进制日志,所以Master与Slave是分别独自工作的两台服务器,数据最终会通过二进制日志达到一致。

异步复制的性能最好,因为它对数据库本身几乎没有任何开销,除非主从延迟非常大,Dump Thread需要读取大量二进制日志文件。

如果业务对于数据一致性要求不高,当发送故障时,能容忍数据的丢失,甚至大量的丢失,推荐用异步复制,这样性能最好(比如像微博这样的业务,虽然他对性能的要求极高,但对于数据丢失,通常可以容忍)。但往往核心业务系统最关心的就是数据安全,比如监控业务、告警系统。

半同步复制

半同步复制要求Mater事务提交过程中,至少有N个Slave接收到二进制日志,这样就能保证当Master发生宕机,至少有N台Slave数据库中过的数据是完整的。

半同步复制并不是MySQL内置的功能,而需要安装半同步插件,并启用半同步复制功能,设置N个Slave接收二进制日志成功,比如:

plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
rpl-semi-sync-master-enabled = 1
rpl-semi-sync-slave-enabled = 1
rpl_semi_sync_master_wait_no_slave = 1

上面的配置中:

  • 第 1 行要求数据库启动时安装半同步插件;

  • 第 2、3 行表示分别启用半同步 Master 和半同步 Slave 插件;

  • 第 4 行表示半同步复制过程中,提交的事务必须至少有一个 Slave 接收到二进制日志。

在半同步复制中,有损半同步复制是MySQL5.7版本以前的半同步复制机制,这种半同步复制在Master发生宕机时,Slave会丢失最后一批提交的数据,若这时Slave提升为Master,可能会发生已经提交的事务不见了,发生了回滚的情况,如下图:

有损半同步

有损半同步在事务提交之后,即步骤4后,等待Slave返回ACK,表示至少有Slave接收到了二进制文件,如果这时二进制文件未发送到Slave,Master就宕机,则此时Slave就会丢失Master已经提交的数据。

而MySQL5.7的无损半同步解决了这个问题,其原理如下:

无损半同步

无损半同步复制WAIT ACK发生在事务提交之前,这样即便Slave没有收到二进制日志,Master就宕机了,由于最后一个事务还没有提交,所以本身这个数据对外也不可见,不存在丢失的问题。

所以,对于任何有数据一致性要求的业务,如电商的核心订单业务、银行、保险、证券等与资金密切相关的业务,务必使用无损半同步复制。这样数据才是安全的、有保障的、即使发送宕机,从机也有一份完整的数据。

多源复制

无论是异步复制还是半同步复制,都是一个Master对应N个Slave。其实MySQL也支持N个Master对应1个Slave,这种架构就称为多源复制。架构如下:

多源复制

上图显示了订单库、库存库、供应商库,通过多源复制同步到同一台MySQL实例上,接着就可以通过MySQL 8.0提供的复杂SQL能力,对业务进行深度的数据分析和挖掘。

延迟复制

前面介绍的复制架构,Slave在接收二进制日志后会尽可能快的回放日志,这样是为了避免主从之间发生延迟。而延迟复制却允许Slave延迟回放接收到的二进制日志,为了避免主服务器的误操作,马上同步到了从服务器,导致数据的完全丢失。

可以通过以下命令配置延迟复制:

CHANGE MASTER TO master_delay=3600

这样就人为设置了Slave落后Master服务器1个小时。

延迟复制在数据库的备份架构设计中非常常见,比如可以配置一个延迟一天的延迟备机,这样本是上说,用户可以得到1份24小时前的快照。

那么当线上发送误操作,如DROP TABLE、DROP DATEBASE这样灾难性的命令时,用户有一个24小时前的快照,数据可以快速恢复。

对于金融行业来说,延迟复制是你备份设计中,必须考虑的架构部分。

总结

复制是数据同步的基础,而二进制日志就是复制的基石。

  • 二进制日志记录了所有对于MySQL变更的操作
  • 可以通过命令SHOW BINLOG EVENTS IN 查看二进制日志的基本信息
  • 可以通过工具mysqlbinlog查看二进制日志的详细信息
  • 复制搭建很简单,但别忘记配置crash safe相关参数,否则可能导致主从数据不一致
  • 异步复制用于非核心场景,不要求数据一致性
  • 无损半同步复制用于核心业务场景,保障数据的一致性
  • 多源复制可将多个Master数据汇总到一个数据库实例中进行分析
  • 延迟复制主要用于误操作防范,金融行业要特别考虑这样的场景

相关文章

评论列表

发表评论:
验证码

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。