在RDS MySQL实例进行主动切换类的运维操作时,应用程序与代理的连接会有短暂的断开,会对业务造成一定影响,您可以参考本文使用连接保持功能,保证连接不断开,提升产品可用性,降低运维成本。
功能简介
RDS MySQL代理的连接保持功能,即在发生主动切换时,能保持应用程序与代理的连接不断开,用户通过代理地址访问数据库的应用程序不会收到连接断开的报错,如下图所示。
包含主动切换的运维操作:
主动主备切换
升级小版本
修改重启类参数(修改参数时需重启实例)
变更主实例配置
实现原理
数据库代理连接分为前端连接(代理与客户端的连接)和后端连接(代理与数据库的连接),在执行主动切换操作时,能够在后端连接断开的情况下,保留前端连接,代理在此基础上实现了连接保持能力。
对于后端数据库是RDS MySQL的连接,连接保持的关键在于后端连接(代理与后端RDS MySQL连接)的连接状态恢复。
RDS MySQL的连接状态通常包括系统变量、用户变量、临时表、字符集编码、事务状态和Prepare语句状态信息等。本文将以set names utf8mb4作为连接状态为例介绍RDS MySQL连接保持的实现原理。
RDS MySQL数据库代理实现连接保持分为三个步骤:
开始切换:阻塞新的连接和新的请求
由于代理不具备事务保持能力,因此,对于不同状态的会话,采取不同的处理方式:
阻塞期间事务活跃的会话:代理将放行请求到后端数据库主节点执行。
阻塞期间新开启的事务的会话:代理将阻塞请求,客户端的现象是阻塞等待服务端回包。
阻塞结束事务仍活跃的会话:客户端与代理的连接将会断开,后端数据库会对未提交的事务进行回滚。
切换中:切换存量连接
说明部分场景下的连接无法保持,详情请参见使用限制。
切换过程中会修改存量连接的切换状态:
无法保持的连接:代理会将整个连接断开。
能够保持的连接:连接将会切换至新的数据库节点。
连接池中原数据库主节点的连接:会被清理。
切换完成:恢复连接
对于能成功保留的连接,代理与后端新的数据库主节点建立连接,并且恢复连接状态。
开启连接保持
2024年01月09日起,符合开启连接保持功能条件的RDS MySQL实例在开通数据库代理时,会默认开启连接保持功能。开启连接保持功能后,您可以随时关闭该功能。
前提条件
RDS实例满足以下条件:
版本:MySQL 5.6或5.7或8.0
系列:高可用
存储类型:云盘
已开通数据库代理,且代理的内核版本不低于1.14.5_20231207。
使用限制
在切换过程中,连接保持功能无法保持如下场景中的连接:
MySQL服务端还没有完全返回回包的连接。例如,100 MB的结果集,只返回了50 MB的结果集,剩余的结果集还在返回中。
存在未提交的事务。
连接上使用过change user语句。
连接上使用过LOAD DATA语句。
存在临时表。
通过代理地址进行Binlog订阅的连接。
不支持FOUND_ROWS、ROW_COUNT和LAST_INSERT_ID函数的调用,这些函数可以调用成功,但是无法保证调用结果的正确性。其中
SELECT FOUND_ROWS()
的用法MySQL官方已不推荐,建议您将SELECT FOUND_ROWS()
替换为SELECT COUNT(*) FROM tb1
进行查询,详情请参见FOUND_ROWS()。
注意事项
由于连接会重连,所以使用
select connection_id()
查询当前连接的thread id可能会变化。由于连接会重连,所以show processlist或者SQL洞察中显示的IP地址和端口,可能会与客户端实际的IP地址和端口不一致。
如果连接上存在用户自己定义的变量,连接能保持,但用户变量会失效。
操作步骤
访问RDS实例列表,在上方选择地域,然后单击目标实例ID。
在左侧导航栏,单击数据库代理。
在基本信息区域,在连接保持右侧单击开启。
关闭连接保持
前提条件
实例已开启连接保持功能。
操作步骤
访问RDS实例列表,在上方选择地域,然后单击目标实例ID。
在左侧导航栏,单击数据库代理。
在基本信息区域,在连接保持右侧单击关闭。
功能测试
测试环境
测试用RDS MySQL实例如下:
MySQL 8.0版本、高可用系列。
实例规格为8核16 GB独享型规格(mysql.x2.xlarge.2c)。
测试工具:Sysbench
测试数据如下:
100张表,其中每张表包含40000行记录数。
并发度为128。
测试方法
在不同运维场景下,测试RDS MySQL实例的连接保活率(即执行运维操作前后的连接保持比例)。
执行测试语句如下:
sysbench --db-driver=mysql --mysql-host=127.X.X.1 --mysql-port=3306 --mysql-user=username --mysql-password='' --tables=100 --table-size=40000 --threads=128 --mysql-db=sbtest --report-interval=5 --time=600 oltp_read_write run
上述测试语句中的关键参数含义如下:
db-driver:数据库引擎
mysql-host:数据库代理地址
tables:数据库中的表数量
table-size:每张表包含的记录条数
threads:并发度
time:测试时间,单位: 秒
测试结果
在如下测试的运维场景中,RDS MySQL实例均能保持100%的连接保活率。
主动切换场景 | 保活率 |
升级小版本 | 100% |
主动主备切换 | 100% |
变更主实例配置 | 100% |
修改重启类参数 | 100% |
相关API
API | 描述 |
修改RDS实例的数据库代理功能。 | |
查询RDS实例的数据库代理详情。 |