MySQL 只读实例延迟

最近更新时间:2024-12-19 17:10:24

我的收藏

背景

在现代高并发的 Web 应用中,数据库的性能和可用性是至关重要的。为了应对大量的读操作和写操作,许多系统采用了 MySQL 的读写分离架构。读写分离通过将读操作和写操作分别分配到不同的数据库实例上,从而提高系统的整体性能和可扩展性。由于 MySQL 存在事务隔离级别,在高并发的场景下可能出现脏读、不可重复读、幻读等场景,表现上均为当一个事务中多次执行同一查询,结果集却不一致的现象。在读写分离的环境中,这类问题更为突出,其主要原因除了高并发产生,也可能是主从数据复制时存在时延,导致从库数据滞后于主库,对业务数据一致性和用户体验造成一定影响。

原理

在 MySQL 的主从架构中,主库负责处理所有的写操作,并将这些操作以二进制日志(Binary Log)的形式记录下来。当进行主从同步时,从库有两个重要的线程:IO 线程和 SQL 线程。
IO 线程负责从主库接收 binlog 事件并将它们写入到 relay log 中。
SQL 线程负责从 relay log 中读取这些事件并应用到从库的数据上。
该故障的实现原理就是通过设置一个 SQL_Delay 的原生参数,当 SQL 线程从 relay log 中读取一个事件时,它会首先检查这个事件的时间戳与当前时间的差值是否小于 SQL_Delay。如果是,那么 SQL 线程就会暂停,直到这个差值大于或等于 SQL_Delay 为止。这样,SQL 线程就会在应用 relay log 中的事件之前等待一定的时间,从而实现了数据的延迟复制。

演练实施

步骤1:演练准备

一台云服务器 CVM 实例,安装 MySQL 客户端。
一台云数据库 MySQL 实例,并配置只读节点,隔离级别为Read committed。示例 MySQL 架构如下:



步骤2:演练编排

1. 登录 云顾问 > 混沌演练控制台,进入演练管理页面,单击新建演练。



2. 单击左下角跳过,新建空白演练,填写演练基本信息。






3. 填写演练动作组信息,选择对象类型 MySQL。然后点击添加实例,添加需要进行演练的实例。


4. 添加演练动作。点击立即添加选择主从延迟故障动作,点击下一步填写相关配置。
该动作可指定故障范围,影响指定可用区的只读实例组,并以秒为单位设置延迟,最多允许设置259200秒,即72小时。



5. 点击下一步确认演练信息无误后,点击提交完成演练创建。




步骤3:执行演练

1. 云服务器 CVM 上启动两个命令行终端,分别连接 MySQL 主实例和只读实例,模拟读写分离的业务架构。
2. 点击执行,开始执行主从延迟故障。


3. 主实例写入数据,只读实例开启事务读取,观察到事务进行过程中相同的查询语句得到的结果不一致,数据不可重复读。
主实例操作:



只读实例操作:



4. 执行回滚动作,恢复至故障前的状态,完成演练。