Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >GreatSQL 中 Insert 慢是什么情况?

GreatSQL 中 Insert 慢是什么情况?

作者头像
GreatSQL社区
发布于 2024-07-06 00:17:48
发布于 2024-07-06 00:17:48
1270
举报

* GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 背景概述 客户反映,业务上某张表的 insert 操作速度很慢,单条 insert 语句的最大执行时间超过了 5 秒。在收到客户问题后,我们仔细检查了数据库状态以及主机的负载情况,发现目前一切正常,并没有发现数据库故障或主机负载过高导致 insert 操作变慢的问题。 因此,我们分析了慢日志,希望从中找出问题。经过分析,发现这条插入语句的query_timelock_time几乎相同,因此怀疑是由于锁等待导致插入操作变慢。随后,我们捕获了通用日志,几乎同一时间这张表有update,insert操作,发现由于更新操作阻塞了插入操作,导致插入速度下降的问题。这个更新操作所在的事务包含了多条 SQL 语句,因此如果该事务执行时间较长,就会阻塞插入操作,导致插入操作的执行时间延长。 问题复现 本次测试基于 GreatSQL 8.0.32-25,隔离级别为 RR 2.1 创建测试表 greatsql> CREATE TABLE `t11` ( `id` int NOT NULL, `c1` int DEFAULT NULL, `c2` int DEFAULT NULL, `c3` int DEFAULT NULL, `c4` int DEFAULT NULL, PRIMARY KEY (`id`), KEY `c2` (`c2`,`c3`), KEY `c4` (`c4`) ); greatsql> insert into t11 values (1,1,1,1,1),(2,2,2,2,2),(3,3,3,3,3),(5,5,5,5,5); 2.2 事务执行顺序 时间事务1事务2T1BEGIN;BEGIN;T2update t10 set c2=20 where c4=2; T3 insert into t10 values (6,2,2,2,2);T4 -- hang住,处于锁等待T5commit;-- 锁等待结束T6 commit; 2.3 事务1执行 greatsql> begin; greatsql> update t11 set c2=20 where c4=2; 查看加锁情况: greatsql> select THREAD_ID,EVENT_ID,ENGINE_LOCK_ID,OBJECT_SCHEMA,OBJECT_NAME,INDEX_NAME,LOCK_TYPE,LOCK_MODE,LOCK_STATUS,LOCK_DATA from performance_schema.data_locks; +-----------+----------+-------------------------------------------+---------------+-------------+------------+-----------+---------------+-------------+-----------+ | THREAD_ID | EVENT_ID | ENGINE_LOCK_ID | OBJECT_SCHEMA | OBJECT_NAME | INDEX_NAME | LOCK_TYPE | LOCK_MODE | LOCK_STATUS | LOCK_DATA | +-----------+----------+-------------------------------------------+---------------+-------------+------------+-----------+---------------+-------------+-----------+ | 55 | 20 | 140531661278568:44172:140531678523168 | test | t11 | NULL | TABLE | IX | GRANTED | NULL | | 55 | 20 | 140531661278568:43110:6:3:140531678129184 | test | t11 | c4 | RECORD | X | GRANTED | 2, 2 | | 55 | 20 | 140531661278568:43110:4:3:140531678129528 | test | t11 | PRIMARY | RECORD | X,REC_NOT_GAP | GRANTED | 2 | | 55 | 20 | 140531661278568:43110:6:4:140531678129872 | test | t11 | c4 | RECORD | X,GAP | GRANTED | 3, 3 | +-----------+----------+-------------------------------------------+---------------+-------------+------------+-----------+---------------+-------------+-----------+ 4 rows in set (0.01 sec) 可以看到此时给【3, 3】这条数据加加了X,GAP锁 2.4 事务2执行 greatsql> begin; greatsql> insert into t11 values (6,2,2,2,2); 查看加锁情况: greatsql> select THREAD_ID,EVENT_ID,ENGINE_LOCK_ID,OBJECT_SCHEMA,OBJECT_NAME,INDEX_NAME,LOCK_TYPE,LOCK_MODE,LOCK_STATUS,LOCK_DATA from performance_schema.data_locks; +-----------+----------+-------------------------------------------+---------------+-------------+------------+-----------+------------------------+-------------+-----------+ | THREAD_ID | EVENT_ID | ENGINE_LOCK_ID | OBJECT_SCHEMA | OBJECT_NAME | INDEX_NAME | LOCK_TYPE | LOCK_MODE | LOCK_STATUS | LOCK_DATA | +-----------+----------+-------------------------------------------+---------------+-------------+------------+-----------+------------------------+-------------+-----------+ | 56 | 14 | 140531661279416:44172:140531678523936 | test | t11 | NULL | TABLE | IX | GRANTED | NULL | | 56 | 14 | 140531661279416:43110:6:4:140531678132256 | test | t11 | c4 | RECORD | X,GAP,INSERT_INTENTION | WAITING | 3, 3 | | 55 | 20 | 140531661278568:44172:140531678523168 | test | t11 | NULL | TABLE | IX | GRANTED | NULL | | 55 | 20 | 140531661278568:43110:6:3:140531678129184 | test | t11 | c4 | RECORD | X | GRANTED | 2, 2 | | 55 | 20 | 140531661278568:43110:4:3:140531678129528 | test | t11 | PRIMARY | RECORD | X,REC_NOT_GAP | GRANTED | 2 | | 55 | 20 | 140531661278568:43110:6:4:140531678129872 | test | t11 | c4 | RECORD | X,GAP | GRANTED | 3, 3 | +-----------+----------+-------------------------------------------+---------------+-------------+------------+-----------+------------------------+-------------+-----------+ 6 rows in set (0.00 sec) greatsql> select REQUESTING_THREAD_ID,REQUESTING_EVENT_ID,REQUESTING_ENGINE_LOCK_ID,BLOCKING_THREAD_ID,BLOCKING_EVENT_ID,BLOCKING_ENGINE_LOCK_ID from performance_schema.data_lock_waits; +----------------------+---------------------+-------------------------------------------+--------------------+-------------------+-------------------------------------------+ | REQUESTING_THREAD_ID | REQUESTING_EVENT_ID | REQUESTING_ENGINE_LOCK_ID | BLOCKING_THREAD_ID | BLOCKING_EVENT_ID | BLOCKING_ENGINE_LOCK_ID | +----------------------+---------------------+-------------------------------------------+--------------------+-------------------+-------------------------------------------+ | 56 | 14 | 140531661279416:43110:6:4:140531678132256 | 55 | 20 | 140531661278568:43110:6:4:140531678129872 | +----------------------+---------------------+-------------------------------------------+--------------------+-------------------+-------------------------------------------+ 1 row in set (0.00 sec) 通过上面2张表,可以看到 X,GAP锁 阻塞了 X,GAP,INSERT_INTENTION 锁2.5 结论 此次Insert慢的原因就是Update语句所在的事务执行时间较长,Update语句产生了GAP锁; Insert语句在执行时此Update语句所在事务还没有执行完成,因此Insert处于锁等待阶段,待Update所在事务提交后Insert才提交; 总结 导致此次问题的原因是 GAP 锁阻塞了 INSERT_INTENTION 锁;因此建议客户在执行 update 操作时,where 条件用主键列,这样可以避免加 GAP 锁。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GreatSQL社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
GreatSQL 死锁案例分析
GreatSQL社区
2024/04/19
890
GreatSQL 死锁案例分析
《叶问》31期,MySQL中如何查询某个表上的IS(意向共享)锁
《叶问》是知数堂新设计的互动栏目,不定期给大家提供技术知识小贴士,形式不限,或提问、或讨论均可,并在当天发布答案,让大家轻轻松松利用碎片时间就可以学到最实用的知识点。
老叶茶馆
2021/05/31
1.6K0
MySQL的insert会阻塞update?
某银行客户在从Oracle迁移到MySQL的开发中,MySQL在READ-COMMITTED隔离级别下,出现了insert阻塞update的情况,但同样的情况下,Oracle的insert则不会阻塞update。本文通过复现该问题,分析MySQL的锁信息,确认是MySQL与Oracle在并发事务处理上的差异,在进行数据库迁移改造的程序开发应予以关注。
bisal
2023/04/06
2.1K0
MySQL Cases-MySQL找出谁持有行锁(RR)
一个事务所做的修改,对其他事务是不可见的,好似是串行执行的。多个事务并行执行的,好似他是串行执行的,事务并发执行,但是效果和串行效果一致,一个事务所做的修改对其他事务是不可见的,好似是串行执行的。
姚崇
2021/08/30
1.5K0
应用示例荟萃 | performance_schema全方位介绍(中)
表级锁对应的instruments(wait/lock/table/sql/handler)默认启用,对应的consumers表为performance_schema.table_handles在setup_consumers只受全局配置项global_instrumentation控制,默认启用。所以,默认情况下只需要设置系统配置参数performance_schema=ON即可,下面我们通过一个示例演示如何找出谁持有表级锁
老叶茶馆
2020/11/26
4350
innodb存储引擎锁的实现
通常,我们在95%以上的MySQL使用场景中,从一定程度上来讲,就是在使用InnoDB存储引擎,很多时候我们选择使用InnoDB存储引擎的原因,就是因为它支持高并发,而高并发的实现很大程度上得益于细粒度的锁实现(行级锁),不仅如此,MySQL 还支持更多灵活多变的锁类型,例如:按照锁类型可分为共享锁(S锁)和排它锁(X锁),按照锁范围可分为记录锁(record lock)、间隙锁(gap lock)、next-key lock。以及一些其他特殊用途的锁。这些锁在不同的隔离级别下存在着不同的表现形式。尤其在RR隔离级别下锁的类型最为丰富、灵活多变。下面我们将为大家一一介绍这些锁的含义和用途。
沃趣科技
2018/08/20
1.1K0
innodb存储引擎锁的实现
MySQL Cases-MySQL找出谁持有行锁(RC)
承接上文RR级别下的锁粒度,这篇文章看下RC模式下有哪些特点,首先说下RC解决了什么问题。
姚崇
2021/08/30
1.3K0
MySQL Cases-MySQL找出谁持有行锁(RC)
INSERT...SELECT语句对查询的表加锁吗
insert into t2 select * from t1; 这条语句会对查询表 t1 加锁吗?不要轻易下结论。对GreatSQL的锁进行研究之前,首先要确认一下事务的隔离级别,不同的事务隔离级别,锁的表现是不一样的。
GreatSQL社区
2024/03/13
2600
INSERT...SELECT语句对查询的表加锁吗
MySQL 8.0:Performance Schema 中锁相关的表
在MySQL 8.0 中,Performance Schema 已经成为监控和分析数据库锁状态的首选方法。 在本文中,我们将探讨Performance Schema中与锁相关的表,并通过实例介绍如何使用这些表来发现当前会话的锁、识别哪些锁被阻塞、以及确定谁持有锁。
用户1278550
2024/01/25
1.4K0
MySQL 8.0:Performance Schema 中锁相关的表
InnoDB数据锁–第2部分“锁”
在InnoDB Data Locking –第1部分“简介”中,我们通过同时编辑电子表格的比喻描述了锁能够解决的难题。虽然通过比喻可以获得直观的感觉,但是我们需要将解决方案与现实进行匹配。在这篇文章中,将讨论我们之前看到的语句如何映射到InnoDB的表,行,锁,锁队列等实际情况,例如“ Alice请求对文件A的读取访问,但必须等待Basil首先释放其写权限”。
MySQLSE
2020/10/29
1K0
应用示例荟萃 | performance_schema全方位介绍(上)
经过前面6个篇幅的学习,相信大家对什么是performance_schema,已经初步形成了一个整体认识,但我想很多同行看完之前的文章之后可能还是一脸懵逼,今天就为大家带来performance_schema系列的最后一个篇章(全系共7个篇章),在这一期里,我们将为大家列举数十个performance_schema应用示例。下面,请跟随我们一起开始performance_schema系统的学习之旅吧。
沃趣科技
2018/07/02
1.3K0
应用示例荟萃 | performance_schema全方位介绍(上)
技术分享 | 如何避免 RC 隔离级别下的 INSERT 死锁
本文分析了 INSERT 及其变种(REPLACE/INSERT ON DUPLICATE KEY UPDATE)的几个场景的死锁及如何避免:
爱可生开源社区
2023/09/09
1.7K1
技术分享 | 如何避免 RC 隔离级别下的 INSERT 死锁
故障分析 | 从 Insert 并发死锁分析 Insert 加锁源码逻辑
即,死锁问题具有业务关联、机制复杂、类型多样等特点,导致当数据库发生死锁问题时,不是那么容易分析。
爱可生开源社区
2023/04/23
1.1K0
MySQL 核心模块揭秘 | 17 期 | InnoDB 有哪几种行锁?
除了以上三类,排他锁(X)还包含另一类有点特殊的锁,就是插入意向锁(LOCK_INSERT_INTENTION)。
爱可生开源社区
2024/05/22
2640
MySQL 核心模块揭秘 | 17 期 | InnoDB 有哪几种行锁?
MySQL中都有哪些锁?
在计算机系统中,锁(Lock)是一种同步机制,用于控制对共享资源的访问。它确保在任何给定时间内只有一个线程能够访问受保护的共享资源,从而避免了由并发访问导致的数据竞争和不一致问题。
Dmego
2023/06/14
1.2K0
MySQL中都有哪些锁?
MySQL 核心模块揭秘 | 36 期 | 非唯一索引等值查询加什么锁?
作者:操盛春,爱可生技术专家,公众号『一树一溪』作者,专注于研究 MySQL 和 OceanBase 源码。
爱可生开源社区
2024/10/10
1920
MySQL 核心模块揭秘 | 36 期 | 非唯一索引等值查询加什么锁?
InnoDB数据锁–第2.5部分“锁”(深入研究)
现在,我们将InnoDB数据锁-第2部分“锁”中了解到的所有知识放在一起,进行深入研究:
MySQLSE
2020/12/08
1.4K0
MySQL 核心模块揭秘 | 42 期 | insert on duplicate 加锁分析(3)
insert 语句插入记录,导致唯一索引冲突,更新主键字段值,这个过程加锁有点多,加锁逻辑也比较复杂。
爱可生开源社区
2024/11/21
1630
MySQL 核心模块揭秘 | 42 期 | insert on duplicate 加锁分析(3)
万字硬核实战分析MySQL死锁
本文先完整介绍MySQL的各种锁类型及加锁机制,之后通过一个案例带大家了解如何分析排查死锁问题。最后,再介绍几种预防死锁的方法。以下是示例表的表结构
会玩code
2022/04/24
9860
万字硬核实战分析MySQL死锁
MySQL 核心模块揭秘 | 41 期 | insert on duplicate 加锁分析(2)
作者:操盛春,爱可生技术专家,公众号『一树一溪』作者,专注于研究 MySQL 和 OceanBase 源码。
爱可生开源社区
2024/11/13
920
MySQL 核心模块揭秘 | 41 期 | insert on duplicate 加锁分析(2)
推荐阅读
相关推荐
GreatSQL 死锁案例分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档