MySQL故障切换之应用无感知设计
作者 沈 刚·沃趣科技数据库技术专家
出品 沃趣科技
|简 介
在数据库中间件读写分离应用场景中,如何保证底层数据库出现故障节点之时,中间件可以快速断开或迁移数据库连接,让用户无感知。
在MySQL数据库中,提供了一个session_track_transaction_info参数来提供解决方案。
因为官方文档上没有对该参数的说明,本文专门介绍该参数的可选值并验证了实际的影响。
|session_track_transaction_info参数
参数介绍
MySQL5.7中,可以通过设置session_track_transaction_info变量来跟踪事务的状态。
该参数存在global以及session两个级别,可以动态修改。
该参数可以设置的值为0(默认OFF),1,2
/**
Transaction tracking level
*/
enum enum_session_track_transaction_info {
TX_TRACK_NONE = 0, ///< do not send tracker items on transaction info
TX_TRACK_STATE = 1, ///< track transaction status
TX_TRACK_CHISTICS = 2 ///< track status and characteristics
};
该参数允许设置的值为0,1,2
设置为0的时候,show variables like %session_track_transaction_info%显示为OFF,表示不开启事务状态跟踪
设置为1的时候,show variables like %session_track_transaction_info%显示为STATE,表示跟踪事务状态
设置为2的时候,show variables like %session_track_transaction_info%显示为CHARACTERISTICS,表示跟踪事务状态和语句
参数设置影响
开启session_track_transaction_info参数的时候,在数据库中无法直接查询到事务状态记录。
根据[WL#4797],MySQL是将事务状态跟踪的信息记录到了每一个Query请求返回的OK packet中。
可以通过抓包的方式查看事务状态信息。
原生MySQL OK packet格式
OK Packet的数据包格式定义
其中int<lenenc>和string<lenenc>中的lenenc表示的是LengthEcode。
MySQL-5.7.19代码中封装OK packet的代码部分在protocol_classic.cc文件中的net_send_ok()函数中。
session_track_transaction_info 额外补充信息
session_track_transaction_info使用8个字符位来表示事务的信息,并且这8个字符信息是保存在COM_QUERY请求语句的返回数据包中的(客户端执行一条语句,都会被封装成MySQL协议中的COM_QUERY请求发送给server端,server端解析执行之后将结果封装在数据包中返回)。
session_track_transaction_info = 0时OK packet格式解析
session_track_transaction_info=0表示不记录事务信息,所有在server端返回的数据包中没有事务状态跟踪信息。
1## session_track_transaction_info = 0
2客户端执行begin;封装的数据包
306 00 00 # playload_length
400 # sequence_id
503 # command_type COM_QUERY
662 65 67 69 6e # begin
7server端返回的数据包:response
807 00 00 # playload_length
901 # sequence_id
1000 # 头部 0x00表示是一个OK包
1100 # 影响的行数 0
1200 # 上次插入的id
1303000000
14客户端执行insert into t1 values(55)封装的数据包
151a 00 00 # playload_length
1600 # sequence_id
1703 # command_type COM_QUERY
18696e7365727420696e746f2074312076616c75657328353529 # insert into t1 values(55)
19server端返回的数据包:response
2007 00 00 # playload_length
2101 # sequence_id
2200010003000000
23客户端执行commit;封装的数据包
2407 00 00 # playload_length
2500 # sequence_id
2603 # command_type COM_QUERY
27636f6d6d6974 # commit
28server端返回的数据库包:response
2907 00 00 # playload_length
3001 # sequence_id
3100000002000000
session_track_transaction_info = 1时OK packet格式解析
1## session_track_transaction_info = 1
2客户端执行begin;封装的数据包
306 00 00 # playload_length
400 # sequence_id
503 # command_type COM_QUERY
6626567696e # begin
7server端返回的数据包:response
814 00 00 # playload_length
901 # sequence_id
1000 # 头部 0x00表示是一个OK包
1100 # 影响的行数 0
1200 # 上次插入的id
1303400000000b050908
1454 5f 5f 5f 5f 5f 5f 5f
15# 事务状态信息 T_______
16# Place 1: 54 //显式的开启一个事务
17# Place 2: 5f //当前事务中没有读取非事务性存储引擎的表
18# Place 3: 5f //当前事务中没有读取事务性存储引擎的表
19# Place 4: 5f //当前事务中没有写入非事务性存储引擎的表
20# Place 5: 5f //当前事务中没有写入事务性存储引擎的表
21# Place 6: 5f //当前事务中没有使用不安全的语句
22# Place 7: 5f //没有结果集
23# Place 8: 5f //没有锁表
24客户端执行insert into t1 values(111)封装的数据包
251b 00 00 # playload_length
2600 # sequence_id
2703 # command_type COM_QUERY
28696e7365727420696e746f2074312076616c7565732831313129 # insert into t1 values(111)
29server端返回的数据包:response
3014 00 00 # playload_length
3101 # sequence_id
3200010003400000000b050908
3354 5f 5f 5f 57 5f 5f 5f # 事务状态信息 T___W___
34# Place 1: 54 //显式的开启一个事务
35# Place 2: 5f //当前事务中没有读取非事务性存储引擎的表
36# Place 3: 5f //当前事务中没有读取事务性存储引擎的表
37# Place 4: 5f //当前事务中没有写入非事务性存储引擎的表
38# Place 5: 57 //当前事务中有写入事务性存储引擎的表
39# Place 6: 5f //当前事务中没有使用不安全的语句
40# Place 7: 5f //没有结果集
41# Place 8: 5f //没有锁表
42客户端执行commit;封装的数据包
4307 00 00 # playload_length
4400 # sequence_id
4503 # command_type COM_QUERY
46636f6d6d6974 # commit
47server端返回的数据包:response
481400000100000002400000000b050908
495f 5f 5f 5f 5f 5f 5f 5f # 事务状态信息________
50# Place 1: 5f //没有活跃的事务
51# Place 2: 5f //当前事务中没有读取非事务性存储引擎的表
52# Place 3: 5f //当前事务中没有读取事务性存储引擎的表
53# Place 4: 5f //当前事务中没有写入非事务性存储引擎的表
54# Place 5: 5f //当前事务中没有写入事务性存储引擎的表
55# Place 6: 5f //当前事务中没有使用不安全的语句
56# Place 7: 5f //没有结果集
57# Place 8: 5f //没有锁表
session_track_transaction_info = 2时OK packet格式解析
将session_track_transaction_info参数设置为2的时候,会显示更加详细的事务状态信息。
1客户端执行begin;封装的数据包
206 00 00 # playload_length
300 # sequence_id
403 # command_type COM_QUERY
5626567696e # begin
6server端返回的数据包:response
729 00 00 # playload_length
801 # sequence_id
9000000034000000020050908
1054 5f 5f 5f 5f 5f 5f 5f # 事务状态信息 T_______
110413125354415254205452414e53414354494f4e3b # START TRANSACTION;
12# Place 1: 54 //显式的开启一个事务
13# Place 2: 5f //当前事务中没有读取非事务性存储引擎的表
14# Place 3: 5f //当前事务中没有读取事务性存储引擎的表
15# Place 4: 5f //当前事务中没有写入非事务性存储引擎的表
16# Place 5: 5f //当前事务中没有写入事务性存储引擎的表
17# Place 6: 5f //当前事务中没有使用不安全的语句
18# Place 7: 5f //没有结果集
19# Place 8: 5f //没有锁表
20客户端执行 insert into t1 values(222)封装的数据包
211b 00 00 # playload_length
2200 # sequence_id
2303 # command_type COM_QUERY
24696e7365727420696e746f2074312076616c7565732832323229 # insert into t1 values(222)
25server端返回的数据包:response
2614 00 00 # playload_length
2701 # sequence_id
2800010003400000000b050908
2954 5f 5f 5f 57 5f 5f 5f # 事务状态信息 T___W___
30# Place 1: 5f //没有活跃的事务
31# Place 2: 5f //当前事务中没有读取非事务性存储引擎的表
32# Place 3: 5f //当前事务中没有读取事务性存储引擎的表
33# Place 4: 5f //当前事务中没有写入非事务性存储引擎的表
34# Place 5: 5f //当前事务中没有写入事务性存储引擎的表
35# Place 6: 5f //当前事务中没有使用不安全的语句
36# Place 7: 5f //没有结果集
37# Place 8: 5f //没有锁表
38客户端执行commit;封装的数据包
3907 00 00 # playload_length
4000 # sequence_id
4103 # command_type COM_QUERY
42636f6d6d6974 # commit
43server端返回的数据包:response
4417 00 00 # playload_length
4501 # sequence_id
4600000002400000000e050908
475f 5f 5f 5f 5f 5f 5f 5f # 事务状态信息 ________
48040100
49# Place 1: 5f //没有活跃的事务
50# Place 2: 5f //当前事务中没有读取非事务性存储引擎的表
51# Place 3: 5f //当前事务中没有读取事务性存储引擎的表
52# Place 4: 5f //当前事务中没有写入非事务性存储引擎的表
53# Place 5: 5f //当前事务中没有写入事务性存储引擎的表
54# Place 6: 5f //当前事务中没有使用不安全的语句
55# Place 7: 5f //没有结果集
56# Place 8: 5f //没有锁表
|总 结
在设置session_track_transaction_info参数之后,在MySQL的返回数据包中可以获取到当前连接的事务状态信息。
在数据库中间件上,利用这一特性,使得MySQL故障的情况下,能够自动迁移连接,减少对用户影响。
在部分场景下能够达到底层MySQL节点故障切换了,对应用来说可以无感知的切换过去。
|作者简介
沈 刚·沃趣科技数据库技术专家
熟悉MySQL数据库运行机制,丰富的数据库及复制架构故障诊断、性能调优、数据库备份恢复及迁移经验。
相关链接
翻过那座山,就能看见海|kubernetes让DBA更优雅地管理数据库
更多干货,欢迎来撩~