暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

万里数据库GreatDB分布式事务(DTM)全解

原创 Dbb 2024-05-23
1204

GreatDB cluster分布式事务(DTM)

DTM(Distributed Transaction Manager)分布式事务管理器为GreatDB cluster组件,提供分布式事务ID(DTID,全局唯一的编号,全局递增)和全局活跃事务视图,用于进行全局的事务控制和隔离级别的实现。自5.1.8版本引入。

DTM架构

DTM本身是经典的C-S架构,集成在GreatDB 引擎中,以组件的形式部署、启用。

当DTM启用后,GreatDB cluster存在唯一一个SQLNode担任DTM Server角色,至少存在一个SQLNode担任DTM Client角色; DTM Client的数量取决于GreatDB cluster的规模。 GreatDB cluster SQLNode都可以担任DTM Client角色。


DTM server由GreatDB cluster内部机制(Gdb task)选取,GreatDB cluster中存在一个DTM_SERVER task,抢占到此任务的SQLNode成为DTM server,无法手动指定。当DTM server所属SQLNode离线,集群中SQLNode通过重新抢占DTM_SERVER task来选举新的DTM server。由于DTM server内部的全局活跃事务视图全部维护在内存中,DTM server切换后全局活跃事务视图丢失。

DTM集成在GreatDB引擎中,DTM未增加新的探活机制,完全依赖SQLNode探活机制。

DTM没有主从概念。GreatDB cluster只有1个DTM server节点,server节点网络延迟会拖慢集群的整体性能,现阶段没有内部机制处理此问题。

DTM事务模型

LTA: Local Trx Agent,即单机本地事务机制。

在支持DTM之前,依靠单机本地事务机制LTA(Local Transaction Agent)保证事务特性。支持DTM后,DTM与LTA协同工作,实现分布式事务特性:

支持分布式事务的原子性,保证分布式事务整体提交或者回滚;

支持分布式事务一致性,DTM+LTA基于MVCC机制组合实现分布式RC、RR隔离级别

一个简单的DTM事务中DTM相关的交互:

  1. 事务开启时,SQLNode从DTM server获取DTID

  2. 根据不同的隔离级别,SQLNode从DTM获取snapshot(全局一致性事务视图)

  3. SQLNode将全局事务信息(DTID+ snapshot)带入到DataNode

  4. DataNode根据DTM信息和LTA进行数据的可见性判断

针对RC和RR不同的隔离级别,主要的区别在于获取snapshot的时机:

RC隔离级别下,针对每个语句都要从DTM获取snapshot

RR隔离级别下,只在事务启动时获取一次snapshot

DTM安装部署

DTM的引入并未对GreatDB cluster的安装部署带来任何冲击,可以按常规的方式部署GreatDB cluster,只需要在GreatDB cluster SQLNode配置文件中添加DTM专有配置参数即可启动DTM事务特性。DataNode的部署不需要任何调整。

DTM参数说明

功能相关参数

参数名称说明参数值
greatdb_enable_dtm是否启用 DTM 分布式事务
如果要启用 DTM 分布式事务,
GreatDB 集群中所有 SQLNode 都需要指定
greatdb_enable_dtm=ON
布尔类型
默认值:OFF
greatdb_dtm_server_candidate当前 SQLNode 是否可以成为DTM Server
如果要保证 DTM 高可用,所有 SQLNode 都需要指定
greatdb_dtm_server_candidate=ON,
如果greatdb_dtm_server_candidate=OFF,
当前SQLNode不能成为DTM Server
布尔类型
默认值:true
greatdb_dtm_server_portDTM Server 监听端口。
当 DTM Server 启动后,DTM Server
的后端线程会在该端口监听连接请求。
整形值
默认值:10000
范围:[1025,65534]
greatdb_dtm_server_address当前DTM server的地址,
格式为ip:port:timestamp, 可以通过设置
此参数值来手动连接到DTM server。
timestamp为dtm server启动的时间戳
字符串类型
默认值:空
greatdb_dtm_trx_timeoutDTM 事务超时时间,单位:秒
DTM client超过此时间未接收到DTM server回复,
会标记事务失败,触发DTM client
重新连接DTM server
整形值
默认值:6,0表示无限等待
范围:[0, 4294967295]
greatdb_dtm_client_con_countDTM client重新连接DTM server时的重连尝试次数,
超过此重连次数还未重连成功,自动重连失败,
需要手动执行set global greatdb_dtm_server_address
指令触发DTM client重连
整形值
默认值:1000
范围:[1,16384]
greatdb_dtm_client_con_intervalDTM client重新连接DTM
server时的重连间隔,单位:毫秒
整形值
默认值:5000
范围:[1,4294967295]
greatdb_dtm_client_connect_tries用于设置DTM client连接DTM server的
连接超时时间,超时时间以2的指数进行增长
整形值
默认值:4,超时时间为1+2+4+8=15s
范围:[1,1000]
greatdb_dtm_handshake_timeoutDTM内部server与client通信接收
握手消息的超时时间,单位:毫秒
建议参数值小于greatdb_dtm_trx_timeout的一半
整形值
默认值:1000
范围:[1,3600000]
greatdb_dtm_log_fileDTM 日志文件
如果未设置此参数,DTM日志与log_error
日志在同一目录下,如果未设置log_error,
DTM日志会写到/tmp目录下,
DTM日志文件名拼接规则:
dtmservice+greatdb_dtm_server_port.log
字符串类型
默认值:空
greatdb_wait_non_running_xa
_trx_before_dtm_start
DTM server因故障进行切换时,新的DTM server启动前
是否会kill后端数据节点上的活跃事务的连接,
直到没有活跃事务才启动DTM server服务。
开启此参数能够保证DTM server切换瞬间的事务一致性。
开启此参数需要启动performance_schema
下的threads和events_transactions_current系统表
布尔类型
默认值:TRUE
greatdb_dtm_server_sqlnode
_address
当前DTM server所属的sqlnode连接信息,
格式为ip:port。
字符串类型
默认值:空

功能参数配置建议

  • 如果要启用 DTM 分布式事务,所有 SQLNode 都需要指定 loose-greatdb_enable_dtm=ON,如果不是所有SQLNode指定loose-greatdb_enable_dtm=ON,并不会报错,只是loose-greatdb_enable_dtm=OFF的SQLNode依旧使用单机本地事务。

  • loose-greatdb_dtm_server_candidate只有在loose-greatdb_enable_dtm=ON时才有意义,如果要保证 DTM 高可用,所有 SQLNode 都需要指定 loose-greatdb_dtm_server_candidate=ON,greatdb_dtm_server_candidate=OFF的SQLNode无法成为DTM server,如果所有SQLNode都指定greatdb_dtm_server_candidate=OFF,GreatDB cluster无法提供事务操作。

  • greatdb_dtm_server_port端口被占用的话,DTM server启动失败,DTM server、client由后台线程启动,启动失败不会给客户端返回失败信息,失败信息记录在SQLNode error日志中。

  • 如果要保证事务原子性,必须指定 loose-greatdb_enable_xa=ON。

  • 如果要保证高可用,建议指定greatdb_dtm_trx_timeout为非0值,能够通过事务超时机制触发DTM client的重连。

  • 当网络延迟较大时,适当调大greatdb_dtm_handshake_timeout但不要超过greatdb_dtm_trx_timeout的一半, 避免因DTM内部通信网络超时导致连接失败。

  • 网络不稳定时,可以调大greatdb_dtm_client_con_count来提高自动重连次数,调大greatdb_dtm_client_connect_tries提高连接超时时间。

  • 发生网络故障时,DTM client内部有自动重连机制,如果网络故障时间很长,在greatdb_dtm_client_con_count指定的重连次数后还未连接成功,可以在网络恢复后,通过set global greatdb_dtm_server_address的方式手动连接到DTM server。

性能相关参数

性能相关参数用于DTM性能调优,一般情况采用默认值即可。如果需要进行性能调优,需要结合服务器的CPU、内存情况进行调整,具体问题具体分析,找出最优值。具体参数说明如下:

参数名称说明参数值
greatdb_dtm_server
_recv_concurrency
DTM Server 端通信层用来接收 DTM Client
请求的并发线程数目
整型值
默认值:8
范围:[1,64]
greatdb_dtm_server
_send_concurrency
DTM Server 端通信层用来给 DTM Client
发送数据的并发线程数目
整型值
默认值:8
范围:[1,64]
greatdb_dtm_client_gen
_view_concurrency
DTM Client 用来生成活跃事务列表的并发线程数目
此参数需要大于greatdb_dtm_readview_read_count
并且为其整倍数
整型值
默认值:8
范围:[1,64]
greatdb_dtm_server
_combine_snap
DTM Servers 是否批量向 DTM Client
发送活跃事务列表,指定为ON时能够减少
网络交互的开销,提升性能
布尔类型
默认值:ON
greatdb_dtm_client
_incr_snap
DTM Client 是否以增量的形式向 DataNode
发送活跃事务列表,指定为ON时SQLNode
只向DataNode发送活跃事务列表中的增量部分,节省网络带宽
布尔类型
默认值:OFF
greatdb_dtm_log_levelDTM 日志输出级别,输出所有小于等于此级别的日志到dtm log文件,日志级别:
DTM_FATAL=0
DTM_ERROR=1
DTM_WARNING=2
DTM_INFO=3
DTM_DEBUG=4
DTM_TRACE=5
global级别可动态修改
整形值
默认值:3
范围:[0,5]
greatdb_dtm_server
_reply_threads
DTM server端处理事务请求回复的线程数量整形值
默认值:8
范围:[1,2048]
greatdb_enable_dml_acquire
_dtm_readview
DTM事务中insert、update、delete、
replace into statement是否获取DTM readview,
为OFF可以减少获取readviwe的网络交互开销,提升性能
布尔类型
默认值:OFF
greatdb_enable_purge
_dtm_xa_log
是否自动清理datanode的DTM xa log,
即是否自动清理mysql.greatdb_dtm_xa_log表中数据
布尔类型
默认值:ON
greatdb_dtm_server_wait
_sync_time
DTM server出现时钟漂移时,DTM server启动事务时
等待时钟同步的超时时间,单位毫秒,超过此时间
DTM server还未完成时钟同步,事务启动失败。
此参数值需要小于greatdb_dtm_trx_timeout值
数值类型
默认值:3000, 0表示不等待时钟同步
范围:[0,4294967295]
greatdb_dtm_async
_commit_level
全局事务异步提交等级,参数取值会影响事务一致性。
0:事务强一致性,保证集群全局事务一致性
1:事务弱一致性,保证单个sqlnode上事务的一致性
不建议生产环境开启此选项
数值类型
默认值:0
范围[0,1]
greatdb_dtm_readview
_wakeup_count
DTM client端唤醒请求readview事务的线程数数值类型
默认值:4
范围[1,32]
greatdb_dtm_readview
_read_count
DTM client端生成readview的线程数
greatdb_dtm_client_gen_view_concurrency
必须大于此参数并为此参数的整倍数。
数值类型
默认值:4
范围[1,32]
greatdb_dtm_trx_async
_commit
DTM事务提交时计算节点向数据节点发送XA COMMIT
是否采用异步模式。
启用异步提交能够提升性能。
布尔类型
默认值:ON
greatdb_dtm_server_time
_persist_timeout
DTM server启动事务时等待greatdb引擎持久化
用于生成DTID的时间戳的超时时间,单位秒。
要求小于greatdb_dtm_trx_timeout,为0表示无限等待。
整型值
默认值:5
范围[0,4294967295]
greatdbdtm_readview
compress
DTM client向datanode发送readview时是否启用压缩。整形值
默认值:1
范围[0,4294967295]

运维相关参数

参数名称说明参数值
greatdb_dtm_trx_available用于显示DTM client是否正常提供服务。
参数值由程序内部设置,不需要手动设置,
DTM client启动成功后将此参数设置为ON,
DTM client出现异常后将此参数设置为OFF。
限制:当MGR网络故障导致SQLNode被剔除出集群后,
greatdb_dtm_trx_available无法准确显示DTM状态,
即只有SQLNode状态为ONLINE时
greatdb_dtm_trx_available能准确显示DTM状态。
布尔类型
默认值:OFF
innodb_greatdb_non_dtm
_upgrade_to_dtm
为非DTM版本升级到DTM版本服务。
DTM版本第一次启动之前,需要打开此参数,
启动DTM版本并确认成功后,必须关闭此参数并重启所有进程。
此参数不能在运行过程中处于打开状态,否则会触发未知的行为。
详细使用方式见手册离线升级DTM升级部分。
布尔类型
默认值:FALSE
innodb_dtm_disableInnoDB引擎是否禁用DTM特性。
DataNode为NODE_MGR模式时,
此参数由程序内部设置,primary状态的DataNode参数值为OFF,
secondary状态的DataNode参数值为ON;
DataNode为NODE_SINGLE模式时,
此参数由配置文件设置,如果GreatDB引擎要启用DTM事务,
此参数需要设置为OFF。
布尔类型
默认值:OFF
greatdb_print_dtm
_debug_info
是否打印DTM相关调试信息,调试信息可打印到DTM日志,
也可打印到log_error日志。系统级别变量,global级别可动态修改。
如果DTM出现异常,可以打开此参数输出DTM调试
信息进行问题定位,注意日志打印量可能非常大,
问题定位后需及时关闭此参数
布尔类型
默认值:OFF
show_dtid_enable_info参数表示show create table是否展示enable_dtid信息:show_dtid_enable_info = DTID_INFO_OFF时,则不显示;show_dtid_enable_info = ENABLE_DTID_INFO_OFF时,对于enable_dtid = OFF则不显示,只显示enable_dtid = ON;show_dtid_enable_info = ENABLE_DTID_INFO_ON时,对于enable_dtid = OFF和enable_dtid = ON都显示。枚举类型
默认值:ENABLE_DTID_INFO_OFF
范围:
DTID_INFO_OFF
ENABLE_DTID_INFO_OFF
ENABLE_DTID_INFO_ON
greatdb_output_dtm_statusshow engine greatdb status是否展示DTM信息整形值
默认值:0
范围:[0,2]
greatdbdtm_trx_perf
track_frequency
show engine greatdb status DTM性能统计
的采样频率,为0关闭DTM性能统计。
详细说明见手册Show Dtm Status说明章节。
整形值
默认值:0
范围:[0,102410241024]
track_mvcc_dtm_footprint是否将可见性判断信息输入到error-log中
0:不输出,> 0:输出
详细说明见手册Show Dtm Status说明章节。
整型值
默认值:0
范围:[0,16]
greatdb_dtm_client_id
_generate_method
client id的生成方式。
GENERATE_BY_SERVER_ID:
client id = server_id
GENERATE_BY_SERVER_UUID:
client id = select CRC32(@@server_uuid)
变量修改后需要重启sqlnode或者
切换DTM server使client id的修改生效
枚举类型
默认值:GENERATE_BY_SERVER_ID
范围:
GENERATE_BY_SERVER_ID
GENERATE_BY_SERVER_UUID

启用DTM事务特性

启用DTM事务特性,greatdb引擎需要开启DTM,并且greatdb引擎的表需要开启enable_dtid属性。

greatdb引擎开启DTM

greatdb引擎启动DTM, 每个client对应一个client id,要求client id在集群范围内是唯一的,如果client id重复,会导致相同client id并且后连接到server的client启动失败,sqlnode error日志中会打印"is duplicated"日志,show engine greatdb status的dtm service status部分也会显示相应信息。

client id生成方式取决于枚举类型系统变量greatdb_dtm_client_id_generate_method,支持的取值有:

  1. GENERATE_BY_SERVER_ID:client id与系统变量server_id相等,client id重复时需要修改sqlnode的server_id。

  2. GENERATE_BY_SERVER_UUID:client id由系统变量server_uuid计算而来,client id=select CRC32(@@server_uuid), server_uuid在sqlnode集群中是唯一的,但函数CRC32的计算结果可能出现重复导致client id重复,此时需要将greatdb_dtm_client_id_generate_method修改为GENERATE_BY_SERVER_ID,使用server_id生成client id。

特别注意,修改server_id或者greatdb_dtm_client_id_generate_method之后,需要重启sqlnode或者切换DTM server使client id的修改生效。

建议所有sqlnode greatdb_dtm_client_id_generate_method采用相同的配置。

启动DTM事务特性需配置以下参数:

loose-greatdb_enable_dtm=ON
loose-greatdb_dtm_server_candidate=ON
loose-greatdb_enable_xa=ON

测试高可用场景(DTM网络异常等)时,需要配置以下参数(可以根据网络延迟、负载等情况调整具体参数值):

loose-greatdb_dtm_trx_timeout=10
loose-greatdb_dtm_client_con_count=5
loose-greatdb_dtm_client_connect_tries=4
loose-greatdb_dtm_handshake_timeout=1000

greatdb_dtm_client_con_count * greatdb_dtm_client_connect_tries 大于故障时间DTM client才能够自动恢复服务,否则需要在故障恢复后,手动通过set global greatdb_dtm_server_address='current_dtm_server_address' 来启动client。

目前获取当前DTM server地址current_dtm_server_address值的方式有2种:

  1. 查询sqlnode的系统变量greatdb_dtm_trx_available,为on的sqlnode上系统变量greatdb_dtm_server_address的值作为current_dtm_server_address

  2. 在所有sqlnode的error日志里搜索"DTM Server started"关键字,最新的日志记录中的字符串即为current_dtm_server_address

greatdb表开启enable_dtid

可以在create table时指定enable_dtid属性,语法如下:

create table t (a int primary key) [enable_dtid=ON|OFF]

可以通过alter table修改enable_dtid属性,语法如下:

alter table t enable_dtid=ON|OFF

enable_dtid属性限制:

  1. create table未指定enable_dtid属性,sqlnode greatdb_enable_dtm=ON时,enable_dtid默认为ON;greatdb_enable_dtm=OFF时,enable_dtid默认为OFF

  2. greatdb_enable_dtm=OFF时,create table或alter table指定enable_dtid=ON会报错

DTM状态查询

DTM 部署后,系统级变量 greatdb_dtm_server_address 为 DTM Server 的地址(ip:port:timestamp), 系统级变量 greatdb_dtm_trx_available 为DTM client是否正常提供服务,如下:

Variable_nameValue
greatdb_dtm_server_address127.0.0.1:8192:1646294691509
greatdb_dtm_trx_availableON

只有在SQLNode状态为ONLINE时,greatdb_dtm_trx_available才能准确显示DTM状态,如果greatdb_dtm_trx_available为OFF,表示当前SQLNode DTM不可用,greatdb_dtm_server_address为过时的DTM server地址。

DTM Server高可用

DTM Server提供高可用服务,当DTM Server节点发生故障,GreatDB Cluster会选取新的SQLNode接管DTM Server服务。DTM Server故障检测依赖现有的SQLNode探活机制,从检测到DTM Server节点发生故障到选举出新的DTM Server节点,期间无法提供DTM服务。

DTID作为GreatDB Cluster全局唯一并且递增的事务编号,依赖DTM Server物理机器的时间。为了确保DTID递增,DTM Server物理机器时间不能回退。DTM Server将生成DTID的时间戳定时持久化到mysql.greatdb_sqlnode_tasks系统表中,可以通过select info from mysql.greatdb_sqlnode_tasks where task_id=3查询持久化的时间戳,查询结果为dtm server daemon task:1646294691502,其中1646294691502为DTM server持久化的毫秒级时间戳, 可以通过系统命令date -d @1646294691.502 将其转换为时间格式。

为了避免服务器系统时间不同导致DTM Server切换时间长,建议在所有SQLNode物理机器上配置NTP进行时间同步。

DTM 2PC事务

2PC将事务的提交分为2个阶段,先prepare,prepare成功之后commit。GreatDB cluster分布式事务2PC提交顺序为DTM prepare、XA prepare、DTM commit、XA commit,XA prepare成功之后XA commit必然成功,因此DTM commit成功之后分布式事务必然能成功提交,所以我们在DTM commit成功之后将事务提交成功返回给客户端,后台异步执行XA commit,给用户更快的事务提交体验。

XA recover

XA recover为后台处理线程,来处理异常的2PC事务。XA recover线程与DTM server在同一个SQLNode中,作为一个后台线程进行工作,每隔xa_recover_interval秒进行一次异常事务监控。

2PC事务prepare成功之后进入prepared状态,当事务涉及到多个shard,只有所有shard的事务都prepare成功进入prepared状态,事务才可以commit。当2PC事务prepared阶段之后有shard内的DataNode连接丢失,事务会进入pending状态,XA recover来处理丢失连接的pending状态事务。

测试Q&A

  • DTM server故障发现机制?

DTM server依赖SQLNode故障发现机制,当SQLNode退出MGR集群时,会触发其他online的SQLNode抢占DTM server task,来选取新的DTM server。

DTM故障发现机制与SQLNode故障发现机制是紧绑定的,只有SQLNode退出MGR集群会触发DTM server的切换。单纯的DTM内部故障不会触发SQLNode离开MGR集群,也就不会触发DTM server切换;

由于DTM故障发现机制依赖SQLNode故障发现机制,故DTM从故障感知到完成切换并没有一个单独的时间指标;

切换过程中新的DTM server故障,如果是网络原因导致并且新DTM server所属的SQLNode离开MGR集群,会触发新一轮的DTM切换,否则不会触发新一轮DTM server切换。

  • DTM Server切换耗时较长问题如何分析?

首先确认切换前后的DTM Server物理机器是否存在时间差,如果后一个DTM Server时间小于前一个DTM Server时间,请先进行时间同步再进行测试;如果不存在时间差,通过sqlnode的error日志和dtm日志进行分析。

最后修改时间:2024-05-23 14:22:32
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论