锁定读、UPDATE 或 DELETE 通常会给在SQL语句处理过程扫描到的每个索引记录上设置记录锁。语句中是否存在排除该行的WHERE条件并不重要。InnoDB不记得确切的WHERE条件,但只知道哪些索引范围被扫描了。锁通常是next-key锁,它也阻止插入到紧挨着记录之前的“间隙”中。然而,间隙锁定可以显式禁用,这会导致next-key锁无法使用。事务隔离级别也会影响到锁的设置。

如果在搜索中使用了二级索引,并且要设置的索引记录锁是互斥的,InnoDB也会检索相应的聚集索引记录并对它们设置锁。

如果没有适合语句的索引,MySQL必须扫描整个表来处理该语句,那么表的每一行都将被锁定,从而阻止其他用户对表的所有插入。创建良好的索引非常重要,这样查询就不会扫描不必要的行。

InnoDB设置的锁的具体类型如下:

1、SELECT ... FROM 是一个一致读,读取数据库的快照并且不设置锁,除非将事务隔离级别设置为SERIALIZABLE。

2、唯一索引的 SELECT ... FOR UPDATE 和 SELECT ... FOR SHARE 语句为扫描的行获取锁,并释放不符合包含在结果集中条件的行(例如,如果它们不满足WHERE子句中给定的条件)的锁。然而,在某些情况下,行可能不会立即被解锁,因为在查询执行期间,结果行与其原始源之间的关系丢失了。例如,在UNION中,从表中扫描(和锁定)的行可能会在评估它们是否符合结果集之前插入临时表。在这种情况下,临时表中的行与原始表中的行之间的关系将丢失,而后者的行直到查询执行结束才被解锁。

3、对于锁定读(带有 FOR UPDATE 或 FOR SHARE 的 SELECT)、UPDATE 和 DELETE 语句,所采用的锁取决于语句是使用具有唯一搜索条件的唯一索引,还是使用范围类型的搜索条件。

  • 对于具有唯一搜索条件的唯一索引,InnoDB 只锁定找到的索引记录,而不锁定它之前的间隙。
  • 对于其他搜索条件和非唯一索引,InnoDB锁定所扫描的索引范围,使用间隙锁或next-key锁阻止其他会话对该范围覆盖的间隙进行插入。 

4、对于搜索遇到的索引记录,SELECT ... FOR UPDATE 阻止其他会话执行 SELECT ... FOR SHARE 或从某些事务隔离级别读取。一致读忽略在读视图中存在的记录上设置的任何锁。

5、UPDATE ... WHERE ... 在搜索遇到的每条记录上设置一个排它的next-key锁。但是,对于使用唯一索引来搜索唯一行的语句,只需要一个索引记录锁。

6、DELETE FROM ... WHERE ... 在搜索遇到的每条记录上设置一个排它的next-key锁。但是,对于使用唯一索引来搜索唯一行的语句,只需要一个索引记录锁。

7、当 UPDATE 修改聚集索引记录时,将对受影响的二级索引记录进行隐式锁定。在插入新的二级索引记录之前执行重复检查扫描,以及在插入新的二级索引记录时,UPDATE操作还会在受影响的二级索引记录上使用共享锁。

8、INSERT 在插入的行上设置排它锁。这个锁是索引记录锁,不是next-key锁(即没有间隙锁),并且不会阻止其他会话插入到插入行之前的间隙中。

9、在插入行之前,设置了一种称为插入意向间隙锁的间隙锁。该锁表示要以这样一种方式插入,即插入到同一索引间隙的多个事务如果不在间隙内的同一位置插入,则不需要相互等待。假设有值为4和7的索引记录。尝试插入值5和6的独立事务在获得插入行上的排它锁之前,每个事务都用插入意向锁锁定4和7之间的间隙,但不会阻塞彼此,因为行是不冲突的。

10、INSERT ... ON DUPLICATE KEY UPDATE 与简单的 INSERT 不同之处在于,当发生重复键错误时,将在要更新的行上放置排他锁而不是共享锁。对重复的主键值采用排它索引记录锁。对重复的唯一键值采用排它的next-key锁。

11、INSERT INTO T SELECT ... FROM S WHERE ... 在插入到 T 的每一行上设置一个排它索引记录锁(没有间隙锁)。如果事务隔离级别为 READ COMMITTED,InnoDB 将 S 上的搜索作为一致 读(无锁)。 否则,InnoDB 在 S 的行上设置共享的 next-key 锁。

12、InnoDB在初始化表上先前指定的AUTO_INCREMENT列时,会在与AUTO_INCREMENT列相关的索引的末尾设置一个排它锁。

13、如果在表上定义了一个FOREIGN KEY约束,那么任何需要检查约束条件的插入、更新或删除都会在它查看的记录上设置共享记录级别的锁,以检查约束。InnoDB会在约束失败的情况下也设置这些锁。

14、LOCK TABLES设置表锁,但是设置这些锁的是InnoDB层之上的MySQL层。如果innodb_table_locks = 1(默认值)和autocommit = 0, InnoDB就知道表锁,而且InnoDB上面的MySQL层知道行级锁。

https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html

给表现加一个意向排它锁,然后给行id=4的行加排它的记录锁,以及正无穷

InnoDB 中不同SQL语句设置的锁的更多相关文章

  1. MySQL innodb中各种SQL语句加锁分析

    概要 Locking read( SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),UPDATE以及DELETE语句通常会在他扫描的索引所 ...

  2. 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,或 ...

  3. 在phpmyadmin中执行sql语句出现的错误:Unknown storage engine 'InnoDB'

    在phpmyadmin中执行sql语句出现的错误:Unknown storage engine 'InnoDB' 解决方法:解决方法:             1.关闭MySQL数据库       2 ...

  4. 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系

    重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...

  5. 【转载】Innodb中的事务隔离级别和锁的关系

    前言 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所 ...

  6. 在mybatis中写sql语句的一些体会

    本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...

  7. [转]在EntityFramework6中执行SQL语句

    本文转自:http://www.cnblogs.com/wujingtao/p/5412329.html 在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有 ...

  8. 在EntityFramework6中执行SQL语句

    在EntityFramework6中执行SQL语句 在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有操作.这一节我来介绍一下如何使用在EF6中执行SQL语 ...

  9. C语言中嵌入式SQL语句

    原文:[转载]C语言中嵌入式SQL语句 http://blog.csdn.net/cnlht/archive/2007/12/12/1930960.aspx原文地址 实验内容: 掌握SQL Serve ...

随机推荐

  1. 274. H-Index - LeetCode

    Question 274. H-Index Solution 题目大意: 论文里的 h 因子判定,题目的意思可能有点晦涩.h 因子是评判学术成就的一种重要方法,h 因子越高越好,h 因子兼顾研究学术人 ...

  2. Linux篇-The slave I/O thread stops because master and slave have equal...

    1)操作系统 cat /etc/issue CentOS release 6.6 (Final) Kernel \r on an \m cat /proc/version Linux version ...

  3. 【万字长文】使用 LSM Tree 思想实现一个 KV 数据库

    目录 设计思路 何为 LSM-Treee 参考资料 整体结构 内存表 WAL SSTable 的结构 SSTable 元素和索引的结构 SSTable Tree 内存中的 SSTable 数据查找过程 ...

  4. K8S Calico网络插件

    0.前言 参考文档:https://github.com/containernetworking/cni Pod网络插件,为了实现Pod网络而需要的插件.组件.由于Kubernetes通过开放的CNI ...

  5. 03-数据结构(C语言版)

    Day01 笔记 1 数据结构基本理论 1.1 算法五个特性: 1.1.1 输入.输出.有穷.确定.可行 1.2 数据结构分类 1.2.1 逻辑结构:集合.线性.树形.图形 1.2.2 物理结构:顺序 ...

  6. 《HelloGitHub》第 74 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...

  7. 碎碎念软件研发02:敏捷之Scrum

    一.什么是 Scrum 1.1 Scrum 定义 Scrum 是敏捷开发方法之一,它使用比较广泛. 敏捷的其它开发方法还有 XP(极限编程).FDD(特性驱动开发).Crystal(水晶方法).TDD ...

  8. boost::bind 不能处理函数重载 (error: no matching function for call to 'bind')

    前言 最近任务多.工期紧,没有时间更新博客,就水一期吧.虽然是水,也不能太失水准,刚好最近工作中遇到一个 boost::bind 的问题,花费了半天时间来定位解决,就说说它吧. 问题背景 项目中使用了 ...

  9. 管理订单状态,该上状态机吗?轻量级状态机COLA StateMachine保姆级入门教程

    前言 在平常的后端项目开发中,状态机模式的使用其实没有大家想象中那么常见,笔者之前由于不在电商领域工作,很少在业务代码中用状态机来管理各种状态,一般都是手动get/set状态值.去年笔者进入了电商领域 ...

  10. FDFS上传文件报错 tracker_query_storage fail, error no: 2, error info: No such file or directo

    原因: 1.tracker服务没有启动 2.Storage服务没有启动 解决方案: 输入命令查看这两个服务是否启动,如果没有则表明没有启动.启动即可. netstat -tulnp tracker服务 ...