Innodb中常见SQL语句设置的锁类型

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 1、select … from除了serializable隔离级别,这种SQL都是一致性非锁定读,不加锁;在serializable级别,这种SQL加next-key锁。2、select … from … lock in share mode这种SQL加S类型的next-key锁。

1、select … from

除了serializable隔离级别,这种SQL都是一致性非锁定读,不加锁;在serializable级别,这种SQL加next-key锁。

2、select … from … lock in share mode

这种SQL加S类型的next-key锁。例如,在会话1上开启事务1,执行如下操作(num列上建有普通二级索引):

mysql> start transaction;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from lock_test;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | jdd  |
|  2 |  43 | hjh  |
|  3 |   6 | ew   |
|  4 |   4 | dd   |
|  5 |  12 | t    |
|  6 |  32 | hu   |
| 32 |  45 | gj   |
+----+-----+------+
mysql> select * from lock_test where num=12 lock in share mode;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  5 |  12 | t    |
+----+-----+------+

会话2上开启事务2,执行如下操作:

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into lock_test values(null,8,'hgj');
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
mysql> insert into lock_test values(null,31,'hgj');
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

插入num=8和31,都发生阻塞,说明事务1执行的语句产生了间隙锁。若再在事务2中执行语句“select * from lock_test where num=12 lock in share mode;”,不会发生阻塞,说明num=12上加的是S锁,所以锁兼容。

3、select … from … for update

这种SQL加X类型的next-key锁。

4、update … where …

RR及其以上隔离级别下,该语句会加next-key锁;在RC级别,只加record锁。

5、delete from … where …

RR及其以上隔离级别下,该语句会加next-key锁;在RC级别,只加record锁。

6、insert … values …

这里指简单的insert(simple insert),即不加ON DUPLICATE KEY UPDATE和select子句的insert语句。这种SQL语句只会在它插入的行上加X锁,而不会加next-key锁。

但是对于唯一列(unique列和主键列),如果多个事务向同一行插入数据,那么第一个事务持有该行的X锁,之后的事务将向这个重复的索引记录行上请求加S锁,并且此时发生锁等待现象。这个时候,还有可能会有死锁发生:

例如假设有个如下结构的innodb表:

CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;

假设有三个会话依次执行如下操作:

Session 1:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 2:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 3:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 1:
ROLLBACK;

会话1获得i=1数据行上的X锁,之后会话2和会话3的操作因为可能会导致重复键错误,所以它们均请求i=1上的S锁而发生锁等待;当会话1回滚后,i=1数据行上的X锁被释放(或者说没有了i=1的行),此时锁请求队列里的会话2和会话3都可以获得S锁,但此时将产生死锁:由于它们都持有该数据行上的S锁,因此两个会话都获取不到数据行上的X锁。
上面的例子,如果i是unique key,情况也同样适用。

7、insert … on duplicate key update

该SQL与simple insert的不同之处在于,当发生重复键错误时,在要更新的行上设置X类型的next-key锁

8、insert into T select … from S where…

这种SQL在T表被插入的行上加X record lock;在S表上,若事务隔离级别不是SERIALIZABLE,innodb在S表上是一致性非锁定读方式(即不加锁)。如果是在SERIALIZABLE级别,innodb将在S表上加S类型的next-key锁。

9、create table … select …

加锁方式和insert … select方式相同。

10、lock tables

包括lock tables tb_name read/write语句,这种语句加的是表锁(table locks),设置表锁的是innodb层之上的MySQL server层

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
|
SQL 存储 Unix
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
70 2
|
1月前
|
SQL 关系型数据库 MySQL
|
1月前
|
SQL
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
33 1
|
2月前
|
SQL 存储 数据库
SQL部分字段编码设置技巧与方法
在SQL数据库管理中,设置字段的编码对于确保数据的正确存储和检索至关重要
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
51 10
|
2月前
|
SQL 存储 关系型数据库
SQL判断CHAR类型字段不为空的方法与技巧
在SQL查询中,判断一个CHAR类型字段是否不为空是一个常见的需求
|
4月前
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?
|
4月前
|
SQL 数据处理 数据库
SQL中的函数有哪些类型
【8月更文挑战第20天】SQL中的函数有哪些类型
50 1
|
4月前
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
76 6
|
4月前
|
SQL 存储 数据库
SQL Server 中的备份类型详解
【8月更文挑战第31天】
100 0