【1】数据库复制本质上就是数据同步。MySQL 数据库是基于二进制日志(binary log)进行数据增量同步,而二进制日志记录了所有对于 MySQL 数据库的修改操作。
在默认 ROW 格式二进制日志中,一条 SQL 操作影响的记录会被全部记录下来,比如一条 SQL语句更新了三行记录,在二进制日志中会记录被修改的这三条记录的前项(before image)和后项(after image)。
【2】MySQL数据复制的本质就是把一台 MySQL 数据库上的变更同步到另一台 MySQL 数据库上。
在 MySQL 复制中,一台是数据库的角色是 Master(也叫 Primary),剩下的服务器角色是 Slave(也叫 Standby):Master 服务器会把数据变更产生的二进制日志通过 Dump 线程发送给 Slave 服务器;Slave 服务器中的 I/O 线程负责接受二进制日志,并保存为中继日志;SQL/Worker 线程负责并行执行中继日志,即在 Slave 服务器上回放 Master 产生的日志。
【异步复制】MySQL默认的复制是异步复制。在异步复制(async replication)中,Master 不用关心 Slave 是否接收到二进制日志,所以 Master 与 Slave 没有任何的依赖关系。异步复制的性能最好,当发生故障时,可能出现数据的丢失。
【半同步复制】半同步复制要求 Master 事务提交过程中,至少有 N 个 Slave 接收到二进制日志,这样就能保证当 Master 发生宕机,至少有 N 台 Slave 服务器中的数据是完整的。半同步复制并不是 MySQL 内置的功能,而是要安装半同步插件,并启用半同步复制功能
半同步复制分为有损半同步复制和无损半同步复制。
有损半同步复制:有损半同步复制是 MySQL 5.7 版本前的半同步复制机制,这种半同步复制在Master 发生宕机时,Slave 会丢失最后一批提交的数据,
无损半同步复制: MySQL 5.7 版本后的的半同步复制机制,该机制会在事务提交前等待从库的ACK响应。对于任何有数据一致性要求的业务,推荐使用无损半同步复制。
【多源复制】多源复制允许在不同 MySQL 实例上的数据同步到 1 台 MySQL 实例上,方便在 1 台 Slave 服务器上进行一些统计查询,如常见的 OLAP 业务查询。
【延迟复制】延迟复制允许Slave 延迟回放接收到的二进制日志,为了避免主服务器上的误操作,马上又同步到了从服务器,导致数据完全丢失。延迟复制在数据库的备份架构设计中非常常见,比如可以设置一个延迟一天的延迟备份,这样本质上说,用户可以有 1 份 24 小时前的快照。
在某些情况下主库和从库会出现一定的延迟,而导致这个延迟的原因很有可能是因为主库执行了比较耗时的delete操作。在生产环境中一定要注意大事务的处理,尽可能使用DROP TABLE/PARTITION操作或者将大事务拆分为小事务。
【1】数据库版本至少要升级到 5.7,因为之前的MySQL 版本从机回放二进制都是单线程的(5.6 是基于库级别的单线程)
【2】从 MySQL 5.7 版本开始,MySQL 支持了从机多线程回放二进制日志的方式,通常把它叫作“并行复制”,官方文档中称为“Multi-Threaded Slave(MTS)”。
【3】MySQL 的从机并行复制有两种模式。
COMMIT ORDER: 主机怎么并行,从机就怎么并行。
WRITESET: 基于每个事务,只要事务更新的记录不冲突,就可以并行。
【基于数据层的数据库高可用架构】基于数据层的数据库高可用架构,就是基于数据同步技术。当主服务器 Master 发生宕机,则故障转移到从服务器 Slave。
为了在故障转移后对 Service 服务无感知,需要引入 VIP(Virtual IP)虚拟 IP 技术,当发生宕机时,VIP 也需要漂移到新的主服务器。
【基于业务层的数据库高可用架构】完全基于业务实现,数据库只是用于存储数据。当一台数据库主服务器不可用,业务直接写另一台数据库主服务器就可以了。
高可用用于处理各种宕机问题,而宕机可以分成服务器宕机、机房级宕机等情况。
机房级宕机: 机房光纤不通/被挖断,机房整体掉电(双路备用电源也不可用);
城市级宕机: 一般指整个城市的进出口网络,骨干交换机发生的故障(这种情况发生的概率很小)。
如果综合考虑的话,高可用就成了一种容灾处理机制,对应的高可用架构的评判标准就上升了。
机房内容灾: 机房内某台数据库服务器不可用,切换到同机房的数据库实例,保障业务连续性;
同城容灾: 机房不可用,切换到同城机房的数据库实例,保障业务连续性;
跨城容灾: 单个城市机房都不可用,切换到跨城机房的数据库实例,保障业务连续性。
除了高可用的容灾架构设计,我们还要做一层兜底服务,用于判断数据的一致性。这里要引入数据核对,用来解决以下两方面的问题。
数据在业务逻辑上一致: 这个保障业务是对的;
主从服务器之间的数据一致: 这个保障从服务器的数据是安全的、可切的。
业务逻辑核对由业务开发负责编写, 从整个业务逻辑调度看账平不平。例如“今天库存的消耗”是否等于“订单明细表中的总和”,“在途快递” + “已收快递”是否等于“已下快递总和”。总之,这是个业务逻辑,用于对账。
主从服务器之间的核对,是由数据库团队负责的。 需要额外写一个主从核对服务,用于保障主从数据的一致性。这个核对不依赖复制本身,也是一种逻辑核对。思路是:将最近一段时间内主服务器上变更过的记录与从服务器核对,从逻辑上验证是否一致。
MySQL 的高可用套件用于负责数据库的 Failover 操作,也就是当数据库发生宕机时,MySQL 可以剔除原有主机,选出新的主机,然后对外提供服务,保证业务的连续性。
MySQL 复制是高可用的技术基础,用于将数据实时同步到从机。高可用套件是MySQL 高可用实现的解决方案,负责切换新主机。
为了不让业务感知到数据库的宕机切换,要用到 VIP(Virtual IP)技术。其中,VIP 不是真实的物理 IP,而是可以随意绑定在任何一台服务器上。
业务访问数据库,不是服务器上与网卡绑定的物理 IP,而是这台服务器上的 VIP。当数据库服务器发生宕机时,高可用套件会把 VIP 插拔到新的服务器上。数据库 Failover后,业务依旧访问的还是 VIP,所以使用 VIP 可以做到对业务透明。
MHA(Master High Availability)是一款开源的 MySQL 高可用程序,它为 MySQL 数据库主从复制架构提供了 automating master failover 的功能。
MHA Manager 通常部署在一台服务器上,用来判断多个 MySQL 高可用组是否可用。当发现有主服务器发生宕机,就发起 failover 操作。MHA Manger 可以看作是 failover 的总控服务器。而 MHA Node 部署在每台 MySQL 服务器上,MHA Manager 通过执行 Node 节点的脚本完成failover 切换操作。
Orchestrator 是另一款开源的 MySQL 高可用套件,除了支持 failover 的切换,还可通过Orchestrator 完成 MySQL 数据库的一些简单的复制管理操作
MGR 是官方在 MySQL 5.7 版本推出的一种基于状态机的数据同步机制。与半同步插件类似,MGR 是通过插件的方式启用或禁用此功能。
MGR是一种高可用解决方案,特别适合应用于对于数据一致性要求极高的金融级业务场景。
MGR 之间的数据同步并没有采用复制技术,而是采用 GCS(Group Communication System)协议的日志同步技术。GSC 本身是一种类似 Paxos 算法的协议,要求组中的大部分节点都接收到日志,事务才能提交。所以,MRG 是严格要求数据一致的,特别适合用于金融级的环境。由于是类 Paxos 算法,集群的节点要求数量是奇数个,这样才能满足大多数的要求。
虽然通过无损半同步复制也能保证主从数据的一致性,但通过 GCS 进行数据同步有着更好的性能:当启用 MGR 插件时,MySQL 会新开启一个端口用于数据的同步,而不是如复制一样使用MySQL 服务端口,这样会大大提升复制的效率。
MGR 是基于 Paxos 算法的数据同步机制,将数据库状态和日志通过 Paxos 算法同步到各个节点,但如果要实现一个完整的数据库高可用解决方案,就需要更高一层级的 InnoDB Cluster 完成。
一个 InnoDB Cluster 由三个组件组成:MGR 集群、MySQL Shell、MySQL Router。具体如下图所示:
其中,MySQL Shell 用来管理 MGR 集群的创建、变更等操作。以后我们最好不要手动去管理 MGR 集群,而是通过 MySQL Shell 封装的各种接口完成 MGR 的各种操作。
为了减少引入 MySQL Router 带来的性能影响,官方建议 MySQL Router 与客户端程序部署在一起,以一种类似 sidecar 的方式进行物理部署。这样能减少额外一次额外的网络开销,基本消除引入 MySQL Router 带来的影响。
所以,这里 MySQL Router 的定位是一种轻量级的路由转发,而不是一个数据库中间件,主要解决数据库切换后,做到对业务无感知。
对于 MySQL 数据库来说,数据库备份分为全量备份、增量备份。
【全量备份】指备份当前时间点数据库中的所有数据,根据备份内容的不同,全量备份可以分为逻辑备份、物理备份两种方式。
逻辑备份:指备份数据库的逻辑内容,就是每张表中的内容通过 INSERT 语句的形式进行备份。MySQL 官方提供的逻辑备份工具有 mysqldump 和 mysqlpump。
关于数据备份还有一款开源的工具非常强大:mydumper 。mydumper 几乎是一个完美的逻辑备份工具,是构建备份系统的首选工具。支持一致性的备份;可以根据表中的记录进行分片,从而进行多线程的备份;对于恢复操作,也可以是多线程的备份;可以指定单个表进行多线程的恢复。
物理备份:物理备份直接备份数据库的物理表空间文件和重做日志,不用通过逻辑的 SELECT 取出数据。所以物理备份的速度,通常是比逻辑备份快的,恢复速度也比较快。但它不如 mydumper 的是,物理备份只能恢复整个实例的数据,而不能按指定表进行恢复。MySQL 8.0 的物理备份工具可以选择官方的 Clone Plugin。
【增量备份】增量备份就是对日志文件进行备份,在 MySQL 数据库中就是二进制日志文件。因为二进制日志保存了对数据库所有变更的修改,所以“全量备份 + 增量备份”,就可以实现基于时间点的恢复(point in time recovery),也就是“通过全量 + 增量备份”可以恢复到任意时间点。增量备份就是使用之前了解的 mysqlbinlog,但这次额外加上了参数 --read-from-remote-server,表示可以从远程某个 MySQL 上拉取二进制日志。MySQL 增量备份的本质是通过 mysqlbinlog 模拟一个 slave 从服务器,然后主服务器不断将二进制日志推送给从服务器,利用之前介绍的复制技术,实现数据库的增量备份。增量备份的恢复,就是通过 mysqlbinlog 解析二进制日志,然后进行恢复。