MySQL复制
二进制日志记录了所有对Mysql变更的操作, 可以通过SHOW BINLOG EVENTS IN .. FROM .. 查看二进制日志的基本信息,通过工具mysqlbinlog 查看二进制日志的详细内容
SHOW BINLOG EVENTS IN 'binlog.00004';
MYSQLBINLOG -vv binlog.000004
配置
复制流程:
- 创建复制所需的账号和权限
- 从Master服务器拷贝一份数据, 使用mysqldump, mysqlpump, code Plugin
- CHANGE MASTER TO 搭建复制关系
- SHOW SLAVE STATUS 观察状态
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
类型
异步复制
Master不关心Slave是否接到二进制日志, Master和Slave没有任何依赖关系,数据通过二进制日志达到一致。
性能最好, 对数据几乎没有开销, 但对数据一致性不高
半同步复制
Master事务提交过程中,至少有N个Slave接收到二进制日志,半同步日志不是MySQL 内置功能,需要安装半同步插件, 启用半同步复制功能。
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
有损半同步复制是Mysql5.7版本前的半同步复制机制, 在Master宕机时,Slave会丢失最后一批提交的数据
- BEGIN
- UPDATE
- INSERT
- COMMIT, 此时发送日志
- WAIT ACK, 返回ACK
无损半同步
- BEGIN
- UPDATE
- INSERT
- WAIT ACK, 此时发送日志, 返回ACK
- COMMIT
多源复制
N个master 对应一个Slave复制
延迟复制
允许Slave延迟回放接收到的日志, 避免主服务器上的误操作
# 人为设置SLave落后1小时
CHANGE MASTER TO master_delay = 3600
主从复制延迟优化
要彻底避免Mysql主从复制延迟,数据库版本至少升级到5.7, 之前的版本从机回放二级制都是单线程的。从 MySQL 5.7 版本开始,MySQL 支持了从机多线程回放二进制日志的方式,通常把它叫作“并行复制”,官方文档中称为“Multi-Threaded Slave(MTS)”。
Mysql两种并行复制:
- COMMIT ORDER : 主机怎么并行, 从机就怎么并行, 主从延迟小。 如果主服务器并行度小, 事务并不小, 可能存在复制延迟。
- WRITESET: 基于每个事务, 只要事务更新的记录不冲突,就可以并行。主从复制几乎没有延迟。
启用WRITESET:
binlog_transaction_dependency_tracking = WRITESET
transaction_write_set_extraction = XXHASH64
slave-parallel-type = LOGICAL_CLOCK
slave-parallel-workers = 16
主从复制延迟监控
Seconds_Behind_Master
SHOW SLAVE STATUS;
此时观察到的Seconds_Behind_Master不准确, 用于严格判断主从延迟问题并不合适。
- 它计算规则是(当前回放二进制时间 - 二进制日志中的时间),如果 I/O 线程有延迟,那么 Second_Behind_Master 为 0,这时可能已经落后非常多了,例如存在有大事务的情况下;
- 对于级联复制,最下游的从服务器延迟是不准确的,因为它只表示和上一级主服务器之间的延迟;
- 若主从时区不一样,那么 second_behind_master 也不准确;
心跳表
主从延迟时间 = 从机当前时间 - 表heartbeat中的时间
USE DBA;
CREATE TABLE heartbeat (
server-uuid VARCHAR(36) PRIMARY KEY,
ts TIMESTAMP(6) NOT NULL
);
CREATE EVENT e_heartbeat
ON SCHEDULE
EVERY 3 SECOND
DO
BEGIN
REPLACE INTO heartbeat VALUES (@@server_uuid,NOW())
END
读写分离设计
读写分离设计的前提是从机不能落后主机很多,最好是能准实时数据同步,务必一定要开始并行复制,并确保线上已经将大事务拆成小事务。
在读取从服务器的Load Balance 服务器,可以配置较小比例的读取请求访问主机,如1%,其余三台从服务器各自承担 33% 的读取请求。如果发生严重的主从复制情况,可以设置下从机权重为 0,将主机权重设置为 100%,这样就不会因为数据延迟,导致对于业务的影响了。
高可用设计
无状态服务高可用设计
发现问题直接转移, 通过负载均衡(如Nginx)服务, 发现有问题,直接剔除。
数据库高可用架构设计
基于数据层
基于数据同步技术,当主服务器宕机后,故障转移到Slave, 重新建立新的拓扑架构。为了在故障转移后对服务无感知,引入VIP技术。
难点在于:
- 如何保证数据一致性(无损复制技术)
- 如何发现主服务器宕机(数据库高可用组件)
- 故障转移逻辑处理
基于业务层
基于业务实现,数据库只是存储数据,当一台主服务器不可用,业务直接写入另一台主服务器,比如订单中的跳单机制。主键生成过程中加入额外信息(服务器编号), 当主服务器一不可用,业务层将订单主键改成服务器二实现高可用。
数据和业务融合实现
将不同编号的订单根据不同的数据库进行存放, DB1仅将 DB1 中的数据同步到 DB2, DB2 仅将DB2 中的数据同步到 DB1, DB1 和DB2将所有数据同步到DB3和DB4中。
高可用部署架构
设计数据强一致的高可用方案时,要选择无损半同步复制,另外在发生宕机FAILOVER 后,若老主机恢复,还需要额外处理老主机上已提交但还未发送到从机的数据。
同城容灾 - 一地三中心
一份数据被存放在了 3 个机房,机房之间根据半同步复制。这里将 MySQL 的半同步复制参rpl_semi_sync_master_wait_for_slave_count 设置为 1,表示只要有 1 个半同步备机接收到日志,主服务器上的事务就可以提交。保证除主机房外,数据在其他机房至少一份完整的数据。
具体策略: 分三个机房, 机房1内有1个 Master, Master 向机房2和机房3内的SLAVE无损半同步复制,同时Master会向机房1和机房2的SLAVE 进行异步复制, 在机房3内可以引入有一个异步复制的延迟备机,用于数据误删除操作的修复。由于Master要向四台备机发送日志, 配置万兆网卡
跨城容灾 - 三地五中心
具体策略: 城市1中的Master无损半同步城市1中机房2, 城市2机房3机房4和城市3机房5数据。
高可用套件
高可用套件用于数据库的failover操作。简单操作可以有VIP和DNS解决方案,组件一般有MHA , Orchestrator。 MHA分为MHA Manger 和 MHA Node。MHA Manager 和 MHA Node 的通信是采用 ssh 的方式,存在潜在的安全风险。,ssh 通信,效率也不是特别高。Orchestrator 基本实现原理与 MHA 是一样的,只是把元数据信息存储在了元数据库中,并且提供了HTTP 接口和命令的访问方式,使用上更为友好。
Innodb Cluster
MySQL 复制只是一种数据同步技术,如果要完成数据库的高可用解决方案,还要额外依赖外部的组件.所有切换判断都是通过一组外部的心跳检查机制完成,这依赖于高可用套件自身的能力,如果高可用套件本身不可靠,就意味着高可用的不可靠性。数据库复制技术的瓶颈在于:只能在一个节点完成写入,然后再将日志同步各个节点,这样单点写入会导致数据库性能无法进行扩展。
MGR技术
MGR 是官方在 MySQL 5.7 版本推出的一种基于状态机的数据同步机制。与半同步插件类似,MGR 是通过插件的方式启用或禁用此功能。特别适合应用于对于数据一致性要求极高的金融级业务场景。
MGR 之间的数据同步并没有采用复制技术,而是采用 GCS(Group Communication System)协议的日志同步技术。GCS 本身是一种类似 Paxos 算法的协议,要求组中的大部分节点都接收到日志,事务才能提交。所以,MRG 是严格要求数据一致的,特别适合用于金融级的环境。由于是类 Paxos 算法,集群的节点要求数量是奇数个,这样才能满足大多数的要求。当启用 MGR 插件时,MySQL 会新开启一个端口用于数据的同步,而不是如复制一样使用MySQL 服务端口,这样会大大提升复制的效率。
MGR 有两种模式:
-
单主(Single Primary)模式;只有一个节点可以写入,MGR 可以自动进行 Failover 切换,不用依赖外部的各种高可用套件,所有的事情都由数据库自己完成
-
多主(Multi Primary)模式。每个节点都可以写入,如果存在冲突,自动回滚其中一个事务,自动保证数据在多个节点中的完整性和一致性。
缺点:
-
仅支持 InnoDB 表,并且每张表一定要有一个主键;
-
目前一个 MGR 集群,最多只支持 9 个节点;
-
有一个节点网络出现抖动或不稳定,会影响集群的性能。
多主注意事项
冲突检测
多主模式要求每个事务在本节点提交时,还要去验证其他节点是否有同样的记录也正在被修改。如果有的话,其中一个事务要被回滚。
自增处理
MGR 多主模式下,我们可以通过设置自增起始值和步长来解决自增的性能问题。参数 group_replication_auto_increment_increment 默认为 7,自增起始值就是 server-id。
Innodb Cluster
一个 InnoDB Cluster 由三个组件组成:MGR 集群、MySQL Shell、MySQL Router。
MySQL Shell 用来管理 MGR 集群的创建、变更等操作。以后我们最好不要手动去管理 MGR 集群,而是通过 MySQL Shell 封装的各种接口完成 MGR 的各种操作。
MySQL Router 是一个轻量级的代理,用于业务访问 MGR 集群中的数据,当 MGR 发生切换时(这里指 Single Primary 模式),自动路由到新的 MGR 主节点,这样业务就不用感知下层MGR 数据的切换。
为了减少引入 MySQL Router 带来的性能影响,官方建议 MySQL Router 与客户端程序部署在一起,以一种类似 sidecar 的方式进行物理部署。这样能减少额外一次额外的网络开销,基本消除引入 MySQL Router 带来的影响。
数据库备份
全量备份
逻辑备份
备份数据库的逻辑内容,每张表中的内容通过 INSERT 语句的形式进行备份。逻辑备份工具有 mysqldump 和 mysqlpump
mysqldump是单线程,速度较慢。
mysqldump -A --single-transaction > backup.sql
参数 -A 表示备份所有数据库;参数 -single-transaction 表示进行一致性备份。如果不加,备份文件内容不一致。或者进行如下配置
# my.cnf
[mysqldump]
single-transaction
mysql < backup.sql
mysqlpump 的使用几乎与 mysqldump 一模一样,唯一不同的是它可以设置备份的线程数
mysqlpump -A --single-transaction --default-parallelism=8 > backup.sql
mysqlpump 的备份多线程是基于多个表的并行备份,mydumper 地址:github.com/maxbube/myd…
mydumper -o /bak -r 100000 --trx-consistency-only -t 8
参数 -r 表示每张表导出 100000 条记录后保存到一张表
参数 --trx-consistency-only 表示一致性备份;
参数 -t 表示 8 个线程并行备份。
物理备份
物理备份直接备份数据库的物理表空间文件和重做日志,不用通过逻辑的 SELECT 取出数据。不如 mydumper 的是,物理备份只能恢复整个实例的数据,而不能按指定表进行恢复。MySQL 8.0 的物理备份工具可以选择官方的 Clone Plugin。
[mysqld]
plugin-load-add=mysql_clone.so
clone=FORCE_PLUS_PERMANENT
mysql> CLONE LOCAL DATA DIRECTORY = '/path/to/clone_dir';
## 远程备份
CLONE INSTANCE FROM 'user'@'host':port
IDENTIFIED BY 'password'
[DATA DIRECTORY [=] 'clone_dir']
[REQUIRE [NO] SSL];
增量备份
mysqlbinlog --read-from-remote-server --host=host_name --raw --stop-never binlog.000001
mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p