我的编程空间,编程开发者的网络收藏夹
学习永远不晚

技术实践丨列存表并发更新时的锁等待问题原理

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

技术实践丨列存表并发更新时的锁等待问题原理

技术实践丨列存表并发更新时的锁等待问题原理

摘要:当开启transaction,执行updata的语句执行成功,不执行commit或rollback;再开启另一个窗口,执行upadate语句,会出现失败(报错:锁等待超时)的情况,但是如果对于上一个窗口执行rollback,此窗口update可以执行成功,该种情况应考虑该表是否为列存表。

本文分享自华为云社区《列存表并发更新时时的锁等待问题原理》,原文作者:PFloyd 。

当开启transaction,执行updata的语句执行成功,不执行commit或rollback;再开启另一个窗口,执行upadate语句,会出现失败(报错:锁等待超时)的情况,但是如果对于上一个窗口执行rollback,此窗口update可以执行成功,该种情况应考虑该表是否为列存表。

【问题根因】

如果使用的是列存表,在事务中执行update操作时,是以CU为单位进行加锁的,所以在事务未提交时并发更新同一CU的其他数据时会出现锁等待的情况,等待超时的时候会出现报错

【机制原理】

1.CU为压缩单元(Compress Unit),列存储的最小单位,导入数据时生成,生成后数据固定不可更改,单个CU最多存储1列60000行数据。同一列的CU连续存储在一个文件中,当大于1G时,切换到新文件中。其中的Ctid字段标识列存表的一行,由cu_id和CU内行号(cu_id, offset)组成;一次性写入的多条的数据位于同一CU。

2. 为了防止页面同一个元组被两个事务同时更新,在进行update时,都会加上行级锁,对于行存来说是对一行数据加锁,对于列存来说就是对一个CU加锁,当一个事务update未提交时,其他事务是无法同时去更新同一CU的数据的。

3.进行update操作后,旧元组被标记为deleted,新元组会写到一个新的CU中

【案例分析】

1.根据现场的报错信息,可以确定是并发更新报错;进行update时,会申请行级锁,在申请行级锁之前会申请transactionid锁,等待超时后报错信息为:waiting for ShareLock on transaction xxx after ..ms

2. 客户反应更新的并不是同一条数据,id不同,询问客户后得知出现问题的是列存表,查询更新的数据是否处于同一CU。

查询后发现处于同一CU,符合预期。

3. 本地场景复现:

起事务执行update操作:

事务未提交并发更新数据出现等待:

查询后发现两条数据位于同一cu:

【相关问题】

为什么update成功一次之后,下一次update就不会互相等锁了?

这是因为update成功之后,旧数据被标记为deleted,新数据写入新的CU,这两条数据不再是同一个CU了,也就不存在这种锁冲突

【处理方案】

列存表不适合频繁的update场景,列存频繁的update容易触发并发更新等锁超时,并且会导致小CU过多,而每个CU都会扩展至8192字节进行对齐,从而导致磁盘空间迅速膨胀;频繁的点查或频繁update场景建议使用行存表。

 

点击关注,第一时间了解华为云新鲜技术~

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

技术实践丨列存表并发更新时的锁等待问题原理

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

技术实践丨列存表并发更新时的锁等待问题原理

摘要:当开启transaction,执行updata的语句执行成功,不执行commit或rollback;再开启另一个窗口,执行upadate语句,会出现失败(报错:锁等待超时)的情况,但是如果对于上一个窗口执行rollback,此窗口update可以执行成功
技术实践丨列存表并发更新时的锁等待问题原理
2021-09-27

编程热搜

目录