小亦平台会持续给大家科普一些运维过程中常见的问题解决案例,运维朋友们可以在常见问题及解决方案专栏查看更多案例。
1. 问题概述
在GaussDB数据库运行过程中,出现事务死锁现象。具体表现为两个线程(ID:28123526878624 与 281317413536672)互相阻塞,导致事务执行中断。
死锁发生时,相关SQL均为对同一张表的并发插入操作,且等待事件显示为"wait available td"。
2. 问题分析
分析过程:
1. 日志追踪:查看DN日志确认死锁线程及互锁关系。通过gs_asp工具定位线程对应的unique_query_id(471524775 与 748623169)。
2. SQL解析:死锁事务均执行对同一张表的INSERT操作,字段高度重合。
3. 等待事件检查: 线程阻塞原因为"wait available td",与Ustore存储引擎的TD机制相关。
4. 故障分析:
1.ustore中有一个td的机制,默认值为4,即允许4个事务并发操作该页面。如果td槽位不足,则会等待td槽位上最小的xid事务结束,才可以继续进行。这个过程在等待事件的层面上一般体现为“wait available td”。
2.等待td槽位上最小的xid事务结束,这件事情是借助事务锁来完成的,所以如果两个事务同时在这两个页面上wait available td,那么可能会造成死锁。
3.客户侧偶现死锁的同时,定位死锁线程等待事件存在wait available td,根据现场同事反馈,插入的值也不存在冲突。
综上,为上述机制导致的偶现死锁问题。
分析结论: 死锁由Ustore的TD槽位竞争机制引发:高并发插入场景下,事务因TD资源不足形成互相等待环路。
3. 解决方案与优化建议
优化措施:
1. 调整init_td大小
详情具体参考《特性指南》的“存储引擎 > Ustore存储引擎 > Ustore简介>Ustore的最佳实践 > 怎么配置init_td大小 ” 章节
2. 调整init_td值的影响
对数据库的影响:
创建UStore表时,指定初始化的TD个数,该参数可以通过alter table进行修改。特别需要注意,该参数会影响数据页面存放的单个元组的最大大小,具体换算方法为MAX_TUPLE_SIZE = BLCKSZ - INIT_TD * TD_SIZE,例如用户将INIT_TD数量从4修改为8,单个元组最大大小会减小4 * INIT_TD大小。
Ustore表(不含toast情况)最大Tuple长度不能超过(8192 - MAXALIGN(56 + init_td * 26 + 4)), 其中MAXALIGN表示8字节对齐。当插入数据长度超过阈值时,用户会收到元组长度过长无法插入的报错。其中init_td对于Tuple长度的影响如下:
•表init_td数量为最小值2时,Tuple长度不能超过8192 - MAXALIGN(56+2*26+4) = 8080B。
•表init_td数量为默认值4时,Tuple长度不能超过8192 - MAXALIGN(56+4*26+4) = 8024B。
•表init_td数量为最大值128时,Tuple长度不能超过8192 - MAXALIGN(56+128*26+4) = 4800B。
对生产业务的影响:
修改该值的语句为DDL语句,注意在无业务的场景下进行。修改完成后,对业务无影响。
遇到死锁问题别慌张,立即提交工单:www.ces-xiaoyi.com.cn/#/workOrder… 小亦平台工程师火速响应,助您快速修复故障!
解锁小亦平台的更多功能:
小亦平台AI巡检Agent现已正式开放!🌟三步实现智能运维,get专业巡检报告:www.ces-xiaoyi.com.cn/#/next_cons…