MySQL/MariaDB 集群技术介绍
1.单机
2.复制
2.1 复制的作用
- 辅助实现备份
- 高可用
- 异地容灾
- 分摊负载
2.2 主从复制
2.2.1 异步(默认)
通过server-id可实现节点间双向复制。
2.2.2 半同步
MySQL 5.5+,可以大大降低数据丢失的风险。
推荐生产环境使用!
- Loss-Less半同步:MySQL 5.7.2+,rpl_semi_sync_master_wait_point参数值:
- AFTER_SYNC,默认值,这个是新的半同步方案,Waiting Slave dump在Storage Commit之前。
- AFTER_COMMIT,这个是老的半同步方案。
- MySQL 5.7对半同步复制作了大改进,新增了一个master线程。
- 在MySQL 5.7以前,master上的binlog dump线程负责两件事:
- dump日志给slave的io_thread;
- 接收来自slave的ack消息。它们是串行方式工作的。
- 在MySQL 5.7中,新增了一个专门负责接受ack消息的线程ack collector thread。这样master上有两个线程独立工作,可以同时发送binlog到slave和接收slave的ack。
- 还新增了几个变量,其中最重要的是 rpl_semi_sync_master_wait_point ,它使得MySQL半同步复制有两种工作模型。
- 从MySQL 5.7.2开始,MySQL支持两种类型的半同步复制。这两种类型由变量 rpl_semi_sync_master_wait_point (MySQL 5.7.2之前没有该变量)控制,它有两种值:AFTER_SYNC和AFTER_COMMIT。
- 在MySQL 5.7.2之后,默认值为AFTER_SYNC,在此版本之前,等价的类型为AFTER_COMMIT。这个变量控制的是master何时提交、何时接收ack以及何时回复成功信息给客户端的时间点。
- AFTER_SYNC模式:master将新事务写进binlog(buffer)后发送给slave,再sync到自己的binlog file(disk), 之后才允许接收slave的ack回复,接收到ack之后才会提交事务,并返回成功信息给客户端。
- AFTER_COMMIT模式:master将新事务写进binlog(buffer)后发送给slave,再sync到自己的binlog file(disk),然后直接提交事务。之后才允许接收slave的ack回复,然后再返回成功信息给客户端。
- 在MySQL 5.7.2之前,等价的模式是 AFTER_COMMIT ,在此版本之后,默认的模式为 AFTER_SYNC ,该模式能最大程度地保证数据安全性,且性能上并不比 AFTER_COMMIT 差。
2.2.3 GTID
推荐生产环境使用!
- 一个事务对应一个唯一ID,一个GTID在一个服务器上只会执行一次。
- GTID是用来代替传统复制的方法,GTID复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置。
- 减少手工干预和降低服务故障时间,当主机挂了之后通过软件从众多的备机中提升一台备机为主机。
- 不支持非事务引擎。
- 不支持create table ... select 语句复制(主库直接报错)。(原理: 会生成两个sql, 一个是DDL创建表SQL, 一个是insert into 插入数据的sql; 由于DDL会导致自动提交, 所以这个sql至少需要两个GTID, 但是GTID模式下, 只能给这个sql生成一个GTID)
- 不允许一个SQL同时更新一个事务引擎表和非事务引擎表。
- 在一个复制组中,必须要求统一开启GTID或者是关闭GTID。
- 开启GTID需要重启 (mysql 5.7除外)。
- 开启GTID后,就不再使用原来的传统复制方式。
- 对于create temporary table 和 drop temporary table语句不支持。
- 不支持sql_slave_skip_counter。
2.2.4 并行复制
解决主从复制延迟问题。
推荐生产环境使用!
多个SQL Thread(从),即并行复制:5.6+
设置参数:slave_parallel_workers
- 基于Schema的,也就是基于库的。如果数据库实例中存在多个Schema,这样设置对于Slave复制的速度可以有比较大的提升。
- 通常情况下单库多表是更常见的一种情形,那基于库的并发就没有什么用。
- 其核心思想是:不同schema下的表并发提交时的数据不会相互影响,即slave节点可以用对relay log中不同的schema各分配一个类似SQL功能的线程,来重放relay log中主库已经提交的事务,保持数据与主库一致。
- 基于schema的并行复制存在两个问题:
- crash safe功能不好做,因为可能之后执行的事务由于并行复制的关系先完成执行,那么当发生crash的时候,这部分的处理逻辑是比较复杂的。
- 最为关键的问题是这样设计的并行复制效果并不高,如果用户实例仅有一个库,那么就无法实现并行回放,甚至性能会比原来的单线程更差。而单库多表是比多库多表更为常见的一种情形。
基于组提交的并行复制(官方称为Enhanced Multi-threaded Slaves,即MTS):5.7+
设置参数:
- slave_parallel_workers > 0 # 一般建议设置4-8,太多的线程会增加线程之间的同步开销。
- global.slave_parallel_type = 'LOGICAL_CLOCK'
变量slave-parallel-type可以有两个值:
- DATABASE 默认值,基于库的并行复制方式,兼容5.6+并行复制
- LOGICAL_CLOCK,基于组提交的并行复制方式,5.7+并行复制
最大化还原主库的并行度:
- 实现方式是在binlog event中增加必要的信息,以便slave节点根据这些信息实现并行复制。
- MySQL5.7的并行复制建立在group commit的基础上,所有在主库上能够完成prepared的语句表示没有数据冲突,就可以在slave节点并行复制。
- 在并行复制环境中,除了在Slave从数据库中配置之外,还需要在Master主数据库上的my.cnf文件中添加binlog_group_commit配置,否则从库无法做到基于事务的并行复制:
- binlog_group_commit_sync_delay = 100
- 这个参数控制着日志在刷盘前日志提交要等待的时间,默认是0也就是说提交后立即刷盘,但是并不代表是关闭了组提交。
- 当设置为0以上的时候,就允许多个事务的日志同时间一起提交刷盘,也就是我们说的组提交。
- 组提交是并行复制的基础,我们设置这个值的大于0就代表打开了组提交的延迟功能,而组提交是默认开启的。最大值只能设置为1 000 000微妙。
- binlog_group_commit_sync_no_delay_count = 10
- 这个参数表示我们在binlog_group_commit_sync_delay等待时间内,如果事务数达到这个参数的设定值,就会触动一次组提交。
- 如果这个值设为0的话就不会有任何的影响。如果到达时间但是事务数并没有达到的话,也是会进行一次组提交操作的。
- binlog_group_commit_sync_delay = 100
支持并行复制的GTID:5.7+
- 在 MySQL 5.7版本中即使不开启GTID,每个事务开始前也是会存在一个Anonymous_Gtid ,而这GTID中就存在着组提交的信息。
- 通过SHOW BINLOG EVENTS,并没有发现有关组提交的任何信息。但是通过mysqlbinlog工具,用户就能发现组提交的内部信息。
- 较之原来的二进制日志内容多了last_committed和sequence_number,last_committed表示事务提交的时候,上次事务提交的编号。
- 如果事务具有相同的last_committed,表示这些事务都在一组内,可以进行并行的回放 (一般是当执行的sql语句并发数大的情况下会进行组提交)。
- 下一个事务的last_committed永远都和上一个事务的sequence_number是相等的,这是因为事务是顺序提交的!这么理解起来并不奇怪。
集群方案介绍
基于 GTID 的主从复制 + 并行复制 + 增强半同步复制 + ProxySQL 读写分离。
2.3 数据一致性检查、同步延迟监控
2.3.1 percona-toolkit
推荐使用!
- 检查master和slave数据的一致性
- 有效地对记录进行归档
- 查找重复的索引
- 对服务器信息进行汇总
- 分析来自日志和tcpdump的查询
- 当系统出问题的时候收集重要的系统信息
- 最主要的三个组件分别是:
- pt-table-checksum:负责监测mysql主从数据一致性
- pt-table-sync:负责当主从数据不一致时修复数据,让它们保存数据的一致性
- pt-heartbeat:负责监控mysql主从同步延迟
2.3.2 同步相关参数
- Seconds_Behind_Master
- Slave_IO_Running
- Slave_SQL_Running
3.中间件(伪需求?)
3.1 MariaDB MaxScale
MariaDB官方,推荐生产环境使用!
- 读写分离
- 基于数据库的分片
- 复制代理
3.2 ProxySQL
Percona主推,推荐生产环境使用!
- 最基本的读/写分离,且方式有多种。
- 可定制基于用户、基于schema、基于语句的规则对SQL语句进行路由。换句话说,规则很灵活。基于schema和与语句级的规则,可以实现简单的sharding。
- 可缓存查询结果。虽然ProxySQL的缓存策略比较简陋,但实现了基本的缓存功能,绝大多数时候也够用了。此外,作者已经打算实现更丰富的缓存策略。
- 监控后端节点。ProxySQL可以监控后端节点的多个指标,包括:ProxySQL和后端的心跳信息,后端节点的read-only/read-write,slave和master的数据同步延迟性(replication lag)。
- 几乎所有的配置均可在线更改(其配置数据基于SQLite存储),无需重启proxysql。
4.集群
4.1 MGR
MySQL组复制,MySQL 5.7.17+, 8.0,单主集群、多主集群。
推荐生产环境使用!
- 分布式集群:基于分布式paxos协议实现组复制,保证数据一致性。
- 高可用:自动检测机制,只要不是大多数节点都宕机就可以继续工作,内置防脑裂保护机制。
- 弹性扩展,最多9个节点:节点的增加与移除会自动更新组成员信息,新节点加入后,自动从其他节点同步增量数据,直到与其他节点数据一致。
- 多节点写入,单/多主模式:提供单主模式和多主模式,单主模式在主库宕机后能够自动选主,所有写入都在主节点进行,多主模式支持多节点写入。
4.2 Oracle NDB Cluster 分片集群
推荐生产环境使用!
- 基于集群的引擎,数据被自动切分并复制到数个机器上(数据节点),适合于那些需要极高查询性能和高可用性的应用。
- NDB提供了高达99.999%的可靠性,在读操作多的应用中表现优异。
4.3 Oracle MySQL InnoDB Cluster & Group Replication
单主集群、多主集群、负载均衡、集群管理。
推荐生产环境使用!
- 适用于有很多并发写操作的应用。
- 利用MGR组复制的 paxos 协议,保障数据一致性,组复制支持单主模式和多主模式。
- 组成部分:
- MySQL Servers with Group Replication:向集群的所有成员复制数据,同时提供容错、自动故障转移和弹性。MySQL Server 5.7.17或更高的版本。生产环境至少需要3个节点保证高可用。
- MySQL Router:确保客户端请求是负载平衡的,并在任何数据库故障时路由到正确的服务器。MySQL Router 2.1.3或更高的版本。生产环境至少需要2个节点搭配Keepalived保证高可用。
- MySQL Shell:通过内置的管理API创建及管理Innodb集群。MySQL Shell 1.0.9或更高的版本。
4.4 MariaDB Galera Cluster
多主集群,原理与Percona XtraDB Cluster一样。
推荐生产环境使用!
4.5 Percona Server & XtraDB Cluster
多主集群。
推荐生产环境使用!
5.高可用方案
5.1 基于主从复制的高可用方案(双节点单向或双向复制 + Keepalived)
- 一般来说,中小型规模的时候,采用这种架构是最省事的。
- 两个节点可以采用简单的一主一从模式,或者双主模式,并且放置于同一个VLAN中,在master节点发生故障后,利用keepalived/heartbeat的高可用机制实现快速切换到slave节点。
5.2 基于Galera协议的高可用方案(MariaDB Galera Cluster 或 Percona XtraDB Cluster)
- Galera是Codership提供的多主数据同步复制机制,可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据一致性。
- 目前PXC用的会比较多一些。MariaDB的集群原理跟PXC一样,MariaDB-Cluster其实就是PXC,两者原理是一样的。
- 推荐配置至少3个节点,但是也可以运行在2个节点上。
- 每个节点都是普通的mysql/percona服务器,可以将现有的数据库服务器组成集群,反之,也可以将集群拆分成单独的服务器。
- 每个节点都包含完整的数据副本。
- 特性:
- 同步复制,事务要么在所有节点提交或不提交。
- 多主复制,可以在任意节点进行写操作。
- 在从服务器上并行应用事件,真正意义上的并行复制。
- 节点自动配置,数据一致性,不再是异步复制。
- 最大的优势:强一致性、无同步延迟。
- 局限性:
- 只支持InnoDB引擎。
- 集群一致性控制机制,事务有可能被终止。
- 写入效率取决于节点中最弱的节点。
- 所有表都要有主键。
- 不支持LOCK TABLE等显式锁操作。
- 锁冲突、死锁问题相对更多。
- 不支持XA。
- 集群吞吐量/性能取决于短板。
- 新加入节点采用SST时代价高。
- 存在写扩大问题。
- 如果并发事务量很大的话,建议采用InfiniBand网络,降低网络延迟。
- 事实上,采用PXC的主要目的是解决数据的一致性问题,高可用是顺带实现的。因为PXC存在写扩大以及短板效应,并发效率会有较大损失,类似semi sync replication机制。
6.常用备份工具
6.1 mysqldump
- 通常为小数据情况下的备份
- innodb:热备,温备
- MyISAM, Aria: 温备
- 单线程备份恢复比较慢
6.2 percona xtrabackup/innobackupex
- 备份大数据量
- 在线(热)备份整个库的InnoDB,XtraDB表
- 在xtrabackup的上一次整库备份基础上做增量备份(innodb only)
- MyISAM温备,不支持增量,只有完全备份
- 以流的形式产生备份,可以直接保存到远程机器上(本机硬盘空间不足时很有用)
- 属于物理备份,速度快
6.3 lvm-snapshot快照备份
- 接近于热备的工具:因为要先请求全局锁,而后创建快照,并在创建快照完成后释放全局锁
- 使用cp、tar等工具进行物理备份
- 备份和恢复速度较快
- 很难实现增量备份,并且请求全局锁需要等待一段时间,在繁忙的服务器上尤其如此
6.4 mariabackup
- Mariabackup最初在MariaDB 10.1.23和MariaDB 10.2.7中发布。它最初在MariaDB 10.1.26和MariaDB 10.2.10中作为GA发布。
- Mariabackup是MariaDB提供的开源工具,用于执行InnoDB,Aria和MyISAM表的物理在线备份。对于InnoDB,可以进行“热在线”备份。它最初是从Percona XtraBackup 2.3.8分叉的。它在Linux和Windows上可用。
7.恢复介绍
- 利用全备的sql文件中记录的CHANGE MASTER语句,binlog文件及其位置点信息,找出binlog文件中增量的那部分。
- --master-data:在备份语句里添加CHANGE MASTER语句以及binlog文件及位置点信息。
- 用mysqlbinlog命令将上述的binlog文件导出为sql文件,并剔除其中的drop语句。
- 通过全备文件和增量binlog文件的导出sql文件,就可以恢复到完整的数据。
8.运维工具
8.1 MySQL Sniffer
第三方SQL语句监控工具。
8.2 general_log
用于跟踪统计SQL执行记录。