GreatSQL 中 Insert 慢是什么情况?
GreatSQL 中 Insert 慢是什么情况?
背景概述
客户反映,业务上某张表的 Insert 操作速度很慢,单条 Insert 语句的最大执行时间超过了 5 秒。在收到客户问题后,我们仔细检查了数据库状态以及主机的负载情况,发现目前一切正常,并没有发现数据库故障或主机负载过高导致 insert 操作变慢的问题。
因此,我们分析了慢日志,希望从中找出问题。经过分析,发现这条插入语句的query_time
和lock_time
几乎相同,因此怀疑是由于锁等待导致插入操作变慢。随后,我们捕获了通用日志,几乎同一时间这张表有update,insert
操作,发现由于更新操作阻塞了插入操作,导致插入速度下降的问题。这个更新操作所在的事务包含了多条 SQL 语句,因此如果该事务执行时间较长,就会阻塞插入操作,导致插入操作的执行时间延长。
问题复现
本次测试基于 GreatSQL-8.0.32-25,隔离级别为 RR
2.1 创建测试表
2.2 事务执行顺序
2.3 事务 1 执行
查看加锁情况:
可以看到此时给【3, 3】这条数据加加了 X,GAP 锁
2.4 事务 2 执行
查看加锁情况:
通过上面 2 张表,可以看到 X,GAP 锁 阻塞了 X,GAP,INSERT_INTENTION 锁;
2.5 结论
此次 insert 慢的原因就是 update 语句所在的事务执行时间较长,update 语句产生了 GAP 锁;
insert 语句在执行时此 update 语句所在事务还没有执行完成,因此 insert 处于锁等待阶段,待 update 所在事务提交后 insert 才提交;
总结
导致此次问题的原因是 GAP 锁阻塞了 INSERT_INTENTION 锁;因此建议客户在执行 update 操作时,where 条件用主键列,这样可以避免加 GAP 锁。
版权声明: 本文为 InfoQ 作者【GreatSQL】的原创文章。
原文链接:【http://xie.infoq.cn/article/1730a7ef3cc7b54a952ff8530】。文章转载请联系作者。
评论