InnoDB中不同SQL语句设置的锁
锁定读(locking read)、更新(UPDATE)或删除(DELETE)通常会在SQL语句处理过程中扫描的每个索引记录上设置记录锁。语句中是否存在排除行的WHERE条件并不重要。InnoDB不记得确切的WHERE条件,而只知道哪个索引范围被扫描。这些锁通常是next-key锁,它还会阻止在记录之前插入“间隙”。然而,间隙锁(gap lock)可以被显式禁用,这会导致不使用next-key锁。
如果在检索中使用了二级索引,并且要设置的索引记录锁是排它的,则InnoDB也会检索相应的聚集索引记录并在它们上设置锁。
执行SQL语句时,如果没有找到可用的索引,MySQL必须扫描整个表来处理该语句,这样的话表的每一行都会被锁定,从而阻塞其他用户对表的所有插入。因此,创建良好的索引非常重要,这样可以避免扫描许多不必要的行。
InnoDB设置特定类型的锁,如下所示:
SELECT ... FROM 是一致读,读取数据库快照,除非将事务隔离级别设置为SERIALIZABLE,否则不设置锁。对于SERIALIZABLE级别,检索会在遇到的索引记录上设置共享的next-key锁。但是,对于使用唯一索引来搜索唯一行的语句,只需要一个索引记录锁。
对于 SELECT ... FOR UPDATE 或者 SELECT ... LOCK IN SHARE MODE ,对扫描的行加锁,并对不符合结果集中包含条件的行(例如,如果它们不满足WHERE子句中给出的条件)释放锁。
SELECT ... LOCK IN SHARE MODE 在所有遇到的索引记录上设置共享的next-key锁。但是,对于使用唯一索引来搜索唯一行的语句,只需要一个索引记录锁。
SELECT ... FOR UPDATE 在搜索遇到的每个记录上设置排它的next-key锁。但是,对于使用唯一索引来搜索唯一行的语句,仅需要索引记录锁定。
UPDATE ... WHERE ... 在搜索遇到的每个记录上设置排它的next-key锁。但是,对于使用唯一索引来搜索唯一行的语句,仅需要索引记录锁定。
DELETE FROM ... WHERE ... 在搜索遇到的每个记录上设置排它的next-key锁。但是,对于使用唯一索引来搜索唯一行的语句,仅需要索引记录锁定。
INSERT 在插入的行上设置排他锁。该锁是索引记录锁,不是next-key锁(即没有间隙锁),并且不会阻止其他会话插入到插入行之前的间隙中。
举个例子,假设有一张表t1,结构如下:
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;
首先Session1获得i=1这一行的排它锁,接下来Session2和Session3由于主键重复只能请求获取该行的共享锁,由于行上已经有排它锁,因此Session2和Session3请求的共享锁不能被立即授予。再接着,Session1回滚,行上的排它锁被释放,于是Session2和Session3在该行上都持有共享锁,此时,死锁发生了,由于对方持有的共享锁,任何一方都不能获得该行的排它锁。
下面这组操作也是类似:
Session 1:
START TRANSACTION;
DELETE FROM t1 WHERE i = 1;
Session 2:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 3:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 1:
COMMIT;
和前面的情况类似,Session1提交以后,Session2和Session3请求该行上的共享锁被立即授予,此时它们再请求获取排它锁时就出现死锁了,因为共享锁被另一个事务持有。
补充: 聚集索引与辅助索引
clustered index (译:聚集索引、聚簇索引)
secondary index (译:二级索引、辅助索引)
每个InnoDB表都有一个特殊的索引,称为聚集索引,用于存储行数据。通常,聚集索引与主键是同义词。为了从查询、插入和其他数据库操作中获得最佳性能,必须了解InnoDB如何使用聚集索引来优化每个表的最常见的查找和DML操作。
Typically, the clustered index is synonymous with the primary key.
通常,“clustered index” 和 “primary key” 是一个意思。
当你在表上定义一个PRIMARY KEY时,InnoDB将它用作聚集索引。为创建的每个表定义一个主键。如果没有逻辑唯一的非空列或列集,请添加一个新的自动递增(auto-increment)列,其值将自动填充。
如果你没有为你的表定义一个PRIMARY KEY,则MySQL会在所有键列都不为NULL的情况下找到第一个唯一索引,并且InnoDB使用它作为聚集索引。
如果表没有主键或合适的唯一索引,InnoDB会在包含行ID值的合成列上内部生成一个名为GEN_CLUST_INDEX的隐藏聚集索引
通过聚集索引访问行非常快,因为索引搜索直接指向包含所有行数据的页。如果表很大,聚集索引体系结构通常节省磁盘I/O操作。
除了聚集索引之外的所有索引都称为二级索引。在InnoDB中,二级索引中的每条记录都包含该行的主键列,以及为二级索引指定的列。InnoDB使用此主键值在聚集索引中搜索行。
如果主键很长,则辅助索引将使用更多空间,因此具有主键较短是比较有利的。
With the exception of spatial indexes, InnoDB indexes are B-tree data structures. Index records are stored in the leaf pages of their B-tree or R-tree data structure. The default size of an index page is 16KB. Supported sizes are 64KB, 32KB, 16KB (default), 8KB, and 4KB.
InnoDB中不同SQL语句设置的锁的更多相关文章
- InnoDB 中不同SQL语句设置的锁
锁定读.UPDATE 或 DELETE 通常会给在SQL语句处理过程扫描到的每个索引记录上设置记录锁.语句中是否存在排除该行的WHERE条件并不重要.InnoDB不记得确切的WHERE条件,但只知道哪 ...
- MySQL innodb中各种SQL语句加锁分析
概要 Locking read( SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),UPDATE以及DELETE语句通常会在他扫描的索引所 ...
- 14.3.3 Locks Set by Different SQL Statements in InnoDB 不同的SQL语句在InnoDB里的锁设置
14.3.3 Locks Set by Different SQL Statements in InnoDB 不同的SQL语句在InnoDB里的锁设置 locking read, 一个UPDATE,或 ...
- 在phpmyadmin中执行sql语句出现的错误:Unknown storage engine 'InnoDB'
在phpmyadmin中执行sql语句出现的错误:Unknown storage engine 'InnoDB' 解决方法:解决方法: 1.关闭MySQL数据库 2 ...
- 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系
重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...
- 【转载】Innodb中的事务隔离级别和锁的关系
前言 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所 ...
- 在mybatis中写sql语句的一些体会
本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...
- [转]在EntityFramework6中执行SQL语句
本文转自:http://www.cnblogs.com/wujingtao/p/5412329.html 在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有 ...
- 在EntityFramework6中执行SQL语句
在EntityFramework6中执行SQL语句 在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有操作.这一节我来介绍一下如何使用在EF6中执行SQL语 ...
- C语言中嵌入式SQL语句
原文:[转载]C语言中嵌入式SQL语句 http://blog.csdn.net/cnlht/archive/2007/12/12/1930960.aspx原文地址 实验内容: 掌握SQL Serve ...
随机推荐
- Laravel - except() 函数
/** * 用户添加 * @param 接收的表单数据 (name,password,id) * @return 返回添加是否成功 */ ...
- 代码使我头疼之React初学习
前言 开始了,去年(2020)说要学的React,到现在2021年的12月底了,才来实施--(年底警告!年末总结还没开始写!) 不过前端为啥要学React呢?Vue不是很好用吗?Vue确实很好用,并且 ...
- JVM大页内存的学习与使用
JVM大页内存的学习与使用 原理和背景 操作系统是计算机的重要组成部分. 现代的操作系统一般都采用 段页式内存管理. 段一般是为了管理和权限 页主要是为了虚拟内存和物理内存的映射. 分页管理可以让物理 ...
- Oracle数据库统计信息_执行计划_sharedpool等的知识梳理
Oracle数据库统计信息_执行计划_sharedpool等的知识梳理 背景 最近有项目出现了年底业务量增加时卡顿的情况. 同事多次发现执行SQL缓慢. 但是重新执行统计信息更新后问题就优化的现象. ...
- [转帖]OutOfMemory JVM参数一览
https://www.cnblogs.com/kuroro/p/11707951.html JVM提供了有用的参数来处理OutOfMemoryError.在本文中,我们要强调那些JVM参数.在对Ou ...
- [转帖]记druid 连接池没满,但超时问题 GetConnectionTimeoutException active 5, maxActive 100
记druid 连接池没满,但超时问题 GetConnectionTimeoutException active 5, maxActive 100 问题说明 线上服务突然出现报错,通过日志查找发现是因为 ...
- [转帖]Windows自带MD5 SHA1 SHA256命令行工具
https://www.cnblogs.com/huangrt/p/13961399.html 检验工具http://www.zdfans.com/html/4346.html HashMyFiles ...
- [转帖]Linux三剑客之sed的初阶使用
https://www.jianshu.com/p/ceea435635a2 大多数情况下,对于文件内容的修改需要依赖交互式的软件来实现,例如vim修改文件的内容则是依赖光标的移动和修改操作来完成对文 ...
- [转帖]美国出口管制条例(EAR)简介
https://zhuanlan.zhihu.com/p/87962305 第一节.美国出口管制法律体系 下述一系列法律.法规及规则,构成美国完整的出口管理制度,是美国各相关执法部门执法的主要法律依据 ...
- Harbor简单搭建以及异常排查的过程与思路
Harbor简单搭建以及异常排查的过程与思路 前言 我发现我总是能够遇到别人遇不到的问题. 本来搭建十分钟就可以搭建完成 结果我硬生生的搭建了四十分钟. 为了保证下次不再浪费时间. 这里加单总结一下遇 ...