MySQL 复制和高可用
date
Aug 8, 2021
slug
mysql-innodb-basic-concept-replication
status
Published
tags
MySQL
summary
type
Page
复制如何工作

- master 写 binlog
- slaver 开启 IO 线程与master 建立连接,在主库上启动一个二进制转储线程 binlog dump,IO 线程接收变更事件,写入 slaver 本地的 relay log
- slaver 启动 SQL 线程,重放 relay log
这种复制架构实现了获取事件和重放事件的解耦,允许这两个过程异步进行。也就是说 I/O 线程能够独立于 SQL 线程之外工作。但这种架构也限制了复制的过程,其中最重要的一点是在主库上并发运行的查询在备库只能串行化执行,因为只有一个 SQL 线程来重放中继日志中的事件。后面我们将会看到,这是很多工作负载的性能瓶颈所在。虽然有一些针对该问题的解决方案,但大多数用户仍然受制于单线程。
还可以将复制传递给更多备库:

通过设置 log_slave_updates 来开启这个功能。但由于从库也要写自己的二进制文件,导致主库和从库上的日志位置肯定不同,这在将备库提升为主库时情况会变得复杂。
复制的原理
基于语句的复制
也叫逻辑复制。就是在从库上重新执行一遍主库上的 SQL。基于语句的复制能够兼容主备上的数据类型差异,如数据类型不同、列顺序不同等等。但由于从库执行 SQL 与主库是有时间差的,导致会出现数据不一致。且在有触发器存在是存在大量 bug。
基于行的复制
将实际数据记录在二进制日志中,可以正确的复制每一行,且能够记录数据修改前的状态,有助于帮助恢复数据。但如果更新影响了很多行,则会将这些行都记录到日志中,造成从库处理变慢导致延迟。比如
UPDATE tal SET a = 0;
这条语句更新全表,导致表中所有行都被记录到了日志中。复制的拓扑
复制的拓扑结构要遵循一下几点:
- 一个 MySQL 备库实例只能有一个主库
- 每个备库必须有一个唯一的服务器 ID
- 一个主库可以有多个备库(相应的一个备库可有多个兄弟备库)
- 如果开启了 log_slave_updates,备库可将数据传播到其他备库
常见拓扑结构:
- 一主多备。适用于读写分离、异地数据中心灾备、建立测试库
- 主动-主动模式下的主主复制(双主复制、双向复制)。可能会用于两地办公室需要同一份可写数据。但其衍生的问题较多,如两台服务器同时修改一行记录。MySQL 5.0 支持设置 aoto_increment_increment 和 auto_increment_offset 将自增 ID 错开,但仍存在问题。
- 主动-被动模式下的主主复制,这种模式下被动服务器是只读的,这使得两台服务器数据和配置都是对称的,故障转移和恢复时主备切换相对容易。
- 环形复制:三个或以上的主库
- 主库、分发主库及备库
- 树或金字塔形
另外MySQL 不支持多主复制(multisource replication),即一个从库有多个主库的情况。
备份的种类
- 热备:不停机不影响线上的备份,也叫在线备份
- 冷备:停机备份,一般只需要复制相关数据库物理文件即可,也叫离线备份。特点是简单、恢复速度快,将文件恢复到指定位置即可,无需执行 SQL 或重建索引。缺点是文件很大,里面有很多 undo 段等等。
- 温备:在线备份,但会影响当前数据库的操作,如加全局锁保证备份一致性
还可按备份后的文件内容分为:逻辑备份和裸文件备份。按备份数据库的内容可分为:完全备份、增量备份、日志备份。
逻辑备份的方式:
- 使用 mysqldump 做逻辑备份
mysqldump --all-databases > dump.sql
- 使用
select [column1],[column2]... info outfile 'filename'
逻辑备份都是 SQL 文件,执行备份文件即可:
load data info table a
mysqlimport
热备可使用
ibbackup
或 XtraBackup
高可用
从两方面考虑:
- 避免单点的出现,重要环节应做冗余备份。
- 如果已然发生故障,应尽快从故障中恢复。
在主备架构下,可提升一台备库成为主库。
在主主架构下可互换两者身份。
还可以通过虚拟 IP 或者中间件避免应用直连,实现快速切换实例。
MySQL-MMM实现MySQL高可用群集:https://www.huaweicloud.com/articles/47647dc7883e275ef8482e80307f2333.html