mysql总结(三)

191 阅读7分钟

6.1 三种集群架构

6.1.1 MMM架构

需要基础资源:

资源数量说明
主DB2用于主备模式的主主复制
从DB0~N台可以根据需要配置N台从服务器
IP地址2n+1N为MySQL服务器的数量
监控用户1用户监控数据库状态的MySQL用户(replication)
代理用户1用于MMM代理端改变read_only状态

故障转移步骤:

  • Slave服务器上的操作

    • 完成原主上已经复制的日志恢复
    • 使用Change Master命令配置新主
  • 主服务器上操作

    • 设置read_only关闭
    • 迁移VIP到新主服务器

优点:

  • 提供了读写VIP的配置,试读写请求都可以达到高可用
  • 工具包相对比较完善,不需要额外的开发脚本
  • 完成故障转移之后可以对MySQL集群进行高可用监控

缺点:

  • 故障简单粗暴,容易丢失事务,建议采用半同步复制方式,减少失败的概率
  • 目前MMM社区已经缺少维护,不支持基于GTID的复制

适用场景:

  • 读写都需要高可用的
  • 基于日志点的复制方式

6.1.2 MHA架构

需要资源:

资源数量说明
主DB2用于主备模式的主主复制
从DB2~N台可以根据需要配置N台从服务器
IP地址n+2N为MySQL服务器的数量
监控用户1用户监控数据库状态的MySQL用户(replication)
复制用户1用于配置MySQL复制的用户

MHA采用的是从slave中选出Master,故障转移:

  • 从服务器:

    • 选举具有最新更新的slave
    • 尝试从宕机的master中保存二进制日志
    • 应用差异的中继日志到其它的slave
    • 应用从master保存的二进制日志
    • 提升选举的slave为master
    • 配置其它的slave向新的master同步

优点:

  • MHA除了支持日志点的复制还支持GTID的方式
  • 同MMM相比,MHA会尝试从旧的Master中恢复旧的二进制日志,只是未必每次都能成功。如果希望更少的数据丢失场景,建议使用MHA架构。

缺点:

  • MHA需要自行开发VIP转移脚本。
  • MHA只监控Master的状态,未监控Slave的状态

6.1.3 MGR架构

MGR是基于现有的MySQL架构实现的复制插件,可以实现多个主对数据进行修改,使用paxos协议复制,不同于异步复制的多Master复制集群。

支持多主模式,但官方推荐单主模式:

  • 多主模式下,客户端可以随机向MySQL节点写入数据
  • 单主模式下,MGR集群会选出primary节点负责写请求,primary节点与其它节点都可以进行读请求处理。

// 查看MGR的组员

select * from performance_schema.replication_group_members;

// 查看MGR的状态

select * from performance_schema.replication_group_member_stats;

// 查看MGR的一些变量

show variables like 'group%';

// 查看服务器是否只读

show variables like 'read_only%';复制代码

优点:

  • 基本无延迟,延迟比异步的小很多
  • 支持多写模式,但是目前还不是很成熟
  • 数据的强一致性,可以保证数据事务不丢失

缺点:

  • 仅支持innodb
  • 只能用在GTID模式下,且日志格式为row格式

适用的业务场景:

  • 对主从延迟比较敏感
  • 希望对对写服务提供高可用,又不想安装第三方软件
  • 数据强一致的场景

6.2 主从复制

备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的:

  1. 在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量。
  2. 在备库 B 上执行 start slave 命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接。
  3. 主库 A 校验完用户名、密码后,开始按照备库 B 传过来的位置,从本地读取 binlog,发给 B。
  4. 备库 B 拿到 binlog 后,写到本地文件,称为中转日志(relay log)。
  5. sql_thread 读取中转日志,解析出日志里的命令,并执行。

6.3 主备延迟分析

6.3.1 主备延迟seconds_behind_master

与数据同步有关的时间点主要包括以下三个:

  1. 主库 A 执行完成一个事务,写入 binlog,我们把这个时刻记为 T1;
  2. 之后传给备库 B,我们把备库 B 接收完这个 binlog 的时刻记为 T2;
  3. 备库 B 执行完成这个事务,我们把这个时刻记为 T3。

所谓主备延迟,就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值,也就是 T3-T1。你可以在备库上执行 show slave status 命令,它的返回结果里面会显示 seconds_behind_master,用于表示当前备库延迟了多少秒。

6.3.2 主备延迟的来源

  • 备库性能差
  • 备库的压力大
  • 大事务,主库上必须等事务执行完成才会写入 binlog,再传给备库
  • SQL Thread主从复制都是单线程的操作,当主库的并发较高时,产生的DML数量超过slave的SQL Thread所能处理的速度,或者当slave中有大型query语句产生了锁等待那么延时就产生了
  • binlog是顺序写,效率很高。Slave的SQL Thread线程将主库的DDL和DML操作事件在slave中重放时操作是随机的,处理速度慢

6.3.3 解决主备延迟方案

  1. 优化网络

  2. 升级Slave硬件配置

  3. Slave调整参数,关闭binlog,修改innodb_flush_log_at_trx_commit参数值

  4. 升级MySQL版本到5.7,使用并行复制

6.3.4 解决主从数据丢失问题

1.半同步复制

从MySQL5.5开始,MySQL已经支持半同步复制了,半同步复制介于异步复制和同步复制之间,主库在执行完事务后不立刻返回结果给客户端,需要等待至少一个从库接收到并写到relay log中才返回结果给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一个TCP/IP往返耗时的延迟。

2.主库配置sync_binlog=1,innodb_flush_log_at_trx_commit=1

sync_binlog的默认值是0,MySQL不会将binlog同步到磁盘,其值表示每写多少binlog同步一次磁盘。

innodb_flush_log_at_trx_commit为1表示每一次事务提交或事务外的指令都需要把日志flush到磁盘。

6.4 主备切换策略

6.4.1 可靠性优先策略

双M结构切换

  1. 判断备库 B 现在的 seconds_behind_master,如果小于某个值(比如 5 秒)继续下一步,否则持续重试这一步;
  2. 把主库 A 改成只读状态,即把 readonly 设置为 true;
  3. 判断备库 B 的 seconds_behind_master 的值,直到这个值变成 0 为止;
  4. 把备库 B 改成可读写状态,也就是把 readonly 设置为 false;把业务请求切到备库 B。

6.4.2 可用性优先策略

可用性优先策略,且 binlog_format=mixed 时的切换流程

  1. 步骤 2 中,主库 A 执行完 insert 语句,插入了一行数据(4,4),之后开始进行主备切换。
  2. 步骤 3 中,由于主备之间有 5 秒的延迟,所以备库 B 还没来得及应用“插入 c=4”这个中转日志,就开始接收客户端“插入 c=5”的命令。
  3. 步骤 4 中,备库 B 插入了一行数据(4,5),并且把这个 binlog 发给主库 A。
  4. 步骤 5 中,备库 B 执行“插入 c=4”这个中转日志,插入了一行数据(5,4)。而直接在备库 B 执行的“插入 c=5”这个语句,传到主库 A,就插入了一行新数据(5,5)。

在实际的应用中,建议使用可靠性优先的策略。毕竟保证数据准确,应该是数据库服务的底线。在这个基础上,通过减少主备延迟,提升系统的可用性。

7.参考文章

极客时间-MySQL实战45讲

time.geekbang.org/column/intr…

Innodb架构

www.cnblogs.com/rickiyang/p…

dev.mysql.com/doc/refman/…

数据结构在线查看

www.cs.usfca.edu/~galles/vis…

索引优化juejin.cn/post/684790…