A locking read, an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of the SQL statement. It does not matter whether there are WHERE conditions in the statement that would exclude the row. InnoDB does not remember the exact WHERE condition, but only knows which index ranges were scanned. The locks are normally next-key locks that also block inserts into the “gap” immediately before the record. However, gap locking can be disabled explicitly, which causes next-key locking not to be used. For more information, see Section 14.3.5.6, “InnoDB Record, Gap, and Next-Key Locks”. The transaction isolation level also can affect which locks are set; see Section 13.3.6, “SET TRANSACTION Syntax”.

一个加锁的read, update, 或者delete通常SQL语句会在每个扫描和处理到的索引记录上加上锁.无论语句中有没有排除这些行的WHERE条件.InnoDB不记得具体的WHERE条件, 它只知道被扫描的索引范围.这些所通常是next-key locks, 他们会阻止记录行之前的间隙的插入操作.然而, gap locking可以被显示禁用.

If a secondary index is used in a search and index record locks to be set are exclusive, InnoDB also retrieves the corresponding clustered index records and sets locks on them.

如果一个辅助索引在查找中被使用, 并且设置的索引记录锁是排他锁, InnoDB将会获取聚簇索引并在他们上面加锁.

Differences between shared and exclusive locks are described in Section 14.3.5.3, “InnoDB Lock Modes”.

If you have no indexes suitable for your statement and MySQL must scan the entire table to process the statement, every row of the table becomes locked, which in turn blocks all inserts by other users to the table. It is important to create good indexes so that your queries do not unnecessarily scan many rows.

如果没有索引符合你的语句,mysql肯定会扫描整个表来处理语句, 这样每一行都会被锁住, 这样会导致所有其他用户的insert语句被阻塞.所以建立正确的索引很重要.

For SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE, locks are acquired for scanned rows, and expected to be released for rows that do not qualify for inclusion in the result set (for example, if they do not meet the criteria given in the WHERE clause). However, in some cases, rows might not be unlocked immediately because the relationship between a result row and its original source is lost during query execution. For example, in aUNION, scanned (and locked) rows from a table might be inserted into a temporary table before evaluation whether they qualify for the result set. In this circumstance, the relationship of the rows in the temporary table to the rows in the original table is lost and the latter rows are not unlocked until the end of query execution.

对于 SELECT ... FOR UPDATE 或者 SELECT ... LOCK IN SHARE MODE, 在扫描行的时候需要获取锁, 但是不包含在结果集里的行的锁会被释放(例如, 如果他们不满足WHERE条件).然而, 在某些情况下, 行可能不会马上解锁, 因为结果行和原始源的关系在查询过程中丢失了.例如, 在UNION时, 扫描表中的(加锁)行可能会在被评估是否符合结果集条件之前,插入到一个临时表.这种情况下, 临时表里行的关系会被丢失,  这样后面的行可能不会被释放直到查询结束

InnoDB sets specific types of locks as follows.

InnoDB设置如下指定类型的锁

  • SELECT ... FROM is a consistent read, reading a snapshot of the database and setting no locks unless the transaction isolation level is set to SERIALIZABLE. For SERIALIZABLE level, the search sets shared next-key locks on the index records it encounters.

  • SELECT ... FROM 是一致性读, 读取数据库的快照, 并且不会设置任何锁, 除非数据库事务隔离级别设置为 SERIALIZABLE. 对于 SERIALIZABLE 级别, 查询集合在遇到的索引记录上设置 shared next-key locks
  • SELECT ... FROM ... LOCK IN SHARE MODE sets shared next-key locks on all index records the search encounters.

  • SELECT ... FROM ... LOCK IN SHARE MODE 会在遇到的所有索引记录上设置 shared next-key locks
  • For index records the search encounters, SELECT ... FROM ... FOR UPDATE blocks other sessions from doingSELECT ... FROM ... LOCK IN SHARE MODE or from reading in certain transaction isolation levels. Consistent reads will ignore any locks set on the records that exist in the read view.

  • SELECT ... FROM ... FOR UPDATE 会阻塞其他会话执行 SELECT ... FROM .. LOCK IN SHARE MODE 或者 在特定事务隔离级别下阻止读取操作. 一致性读会忽视任何设置在记录上的任何锁.
  • UPDATE ... WHERE ... sets an exclusive next-key lock on every record the search encounters.

  • UPDATE ... WHERE ... 设置一个 exclusive next-key lock 在每个他查找是遇到的行里.
  • DELETE FROM ... WHERE ... sets an exclusive next-key lock on every record the search encounters.

  • DELETE FROM ... WHERE ... 同 UPDATE.
  • INSERT sets an exclusive lock on the inserted row. This lock is an index-record lock, not a next-key lock (that is, there is no gap lock) and does not prevent other sessions from inserting into the gap before the inserted row.

  • INSERT 设置一个exclusive lock 在插入行上. 这个锁是一个index-record lock, 不是一个 next-key lock(也就是说, 没有间隙锁)并且不会阻止其他会话插入数据到插入行之前.

    Prior to inserting the row, a type of gap lock called an insertion intention gap lock is set. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6 each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.

  • 在插入行之前, 一种叫做insertion intention gap lock的锁会被设置. 这个锁表示打算插入操作可以这么搞: 多个事务插入同一个索引间隙不需要相互等待, 只要他们不是插入到同一个间隙的同一个点. 假如有索引4,7. 两个事务视图插入5.6到4,7之间, 他们并不会相互阻塞

    If a duplicate-key error occurs, a shared lock on the duplicate index record is set. This use of a shared lock can result in deadlock should there be multiple sessions trying to insert the same row if another session already has an exclusive lock. This can occur if another session deletes the row. Suppose that an InnoDB table t1 has the following structure:

  • 如果一个duplicate-key错误发生了, 重复index记录上会设置shared lock.如果有一个session已经有一个exclusive lock, 但是又有多个session 试图插入同一行 , 这种shared lock 的用法会导致死锁. 这在另一个session删除了这行的时候可能发生.如果innodb表t1有如下结构

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

    Now suppose that three sessions perform the following operations in order:

  • 现在假设有3个session执行如下语句

    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;
    

    The first operation by session 1 acquires an exclusive lock for the row. The operations by sessions 2 and 3 both result in a duplicate-key error and they both request a shared lock for the row. When session 1 rolls back, it releases its exclusive lock on the row and the queued shared lock requests for sessions 2 and 3 are granted. At this point, sessions 2 and 3 deadlock: Neither can acquire an exclusive lock for the row because of the shared lock held by the other.

  • session1第一个操作获取一个排他锁. session 2, 3 的操作会造成duplicate-key错误, 并且都会请求一个那行的shared lock. 当session 1 回滚, 他会释放他的排他锁, 并且session2,3 的shared lock请求会被授权.这是, session 2 3 会死锁: 因为shared lock被对方持有, 所以他们俩个人都无法获取排他锁.

    A similar situation occurs if the table already contains a row with key value 1 and three sessions perform the following operations in order:

  • 一个类似的状况是, 如果表已经包含了一个key为1的行, 并且3个session按顺序执行如下操作:

    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;
    

    The first operation by session 1 acquires an exclusive lock for the row. The operations by sessions 2 and 3 both result in a duplicate-key error and they both request a shared lock for the row. When session 1 commits, it releases its exclusive lock on the row and the queued shared lock requests for sessions 2 and 3 are granted. At this point, sessions 2 and 3 deadlock: Neither can acquire an exclusive lock for the row because of the shared lock held by the other.

  • 由session 1的操作获取一个排他锁. session 2 和 3 的操作会导致duplicate-key error, 并且他们都请你去了一个这一行的共享锁.当session1提交时, 他释放排他锁并且session2和3 的锁会获得授权. 这是, session2和3死锁了: 谁都不能获取排他锁, 因为他们的共享锁都由对方持有
  • INSERT ... ON DUPLICATE KEY UPDATE differs from a simple INSERT in that an exclusive next-key lock rather than a shared lock is placed on the row to be updated when a duplicate-key error occurs.

  • INSERT ... ON DUPLICATE KEY UPDATE 和 简单的INSERT相比有所不同, 他在发生duplicate-key错误的时候, 产生的是exclusive next-key lock而不是shared lock.
  • REPLACE is done like an INSERT if there is no collision on a unique key. Otherwise, an exclusive next-key lock is placed on the row to be replaced.

  • REPLACE在没有其他unique key冲突的时候的会和insert一样完成操作. 否则会在那一行上放置next-key lock.
  • INSERT INTO T SELECT ... FROM S WHERE ... sets an exclusive index record without a gap lock on each row inserted into T. If the transaction isolation level is READ COMMITTED or innodb_locks_unsafe_for_binlog is enabled, and the transaction isolation level is not SERIALIZABLEInnoDB does the search on S as a consistent read (no locks). Otherwise, InnoDB sets shared next-key locks on rows from SInnoDB has to set locks in the latter case: In roll-forward recovery from a backup, every SQL statement must be executed in exactly the same way it was done originally.

  • INSERT INTO T SELECT ... FROM S WHERE ... 设置了一个没有间隙锁的排他索引记录. 如果事务隔离级别是READ_COMMITTED或者innodb_locks_unsafe_for_binlog开启了, 并且事务隔离级别不是SERIALIZABLE, InnoDB查找S时则不是一致性读(没有锁). 另外, InnoDB在S上设置了shared next-key locks. InnoDB必须在后面这种情况必须设锁:  在备份的前滚恢复是, 每条sql必须按照他原来完成的形式那样执行.

    CREATE TABLE ... SELECT ... performs the SELECT with shared next-key locks or as a consistent read, as forINSERT ... SELECT.

    When a SELECT is used in the constructs REPLACE INTO t SELECT ... FROM s WHERE ... or UPDATE t ... WHERE col IN (SELECT ... FROM s ...)InnoDB sets shared next-key locks on rows from table s.

  • While initializing a previously specified AUTO_INCREMENT column on a table, InnoDB sets an exclusive lock on the end of the index associated with the AUTO_INCREMENT column. In accessing the auto-increment counter, InnoDBuses a specific AUTO-INC table lock mode where the lock lasts only to the end of the current SQL statement, not to the end of the entire transaction. Other sessions cannot insert into the table while the AUTO-INC table lock is held; see Section 14.3.5.2, “The InnoDB Transaction Model and Locking”.

    InnoDB fetches the value of a previously initialized AUTO_INCREMENT column without setting any locks.

  • If a FOREIGN KEY constraint is defined on a table, any insert, update, or delete that requires the constraint condition to be checked sets shared record-level locks on the records that it looks at to check the constraint.InnoDB also sets these locks in the case where the constraint fails.

  • LOCK TABLES sets table locks, but it is the higher MySQL layer above the InnoDB layer that sets these locks.InnoDB is aware of table locks if innodb_table_locks = 1 (the default) and autocommit = 0, and the MySQL layer above InnoDB knows about row-level locks.

    Otherwise, InnoDB's automatic deadlock detection cannot detect deadlocks where such table locks are involved. Also, because in this case the higher MySQL layer does not know about row-level locks, it is possible to get a table lock on a table where another session currently has row-level locks. However, this does not endanger transaction integrity, as discussed in Section 14.3.5.10, “Deadlock Detection and Rollback”. See also Section 14.3.9.7, “Limits on InnoDB Tables”.

Locks Set by Different SQL Statements in InnoDB的更多相关文章

  1. 14.5.3 Locks Set by Different SQL Statements in InnoDB

    14.5.3 Locks Set by Different SQL Statements in InnoDB 通过不同的SQL语句设置的锁 在InnoDB中 一个锁定读, 一个UPDATE 或者一个D ...

  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. How to executing direct SQL statements [Axapta, AX4.0, AX2009, AX2012]

    Today I want to talk about executing SQL statements in X++ on both the current AX database and exter ...

  4. Save results to different files when executing multi SQL statements in DB Query Analyzer 7.01

        1 About DB Query Analyzer DB Query Analyzer is presented by Master Genfeng,Ma from Chinese Mainl ...

  5. Access text files using SQL statements by DB Query Analyzer

    Access text files using SQL statements by DB Query Analyzer Ma Gen feng (Guangdong Unitoll Services ...

  6. (11)MySQL进阶篇SQL优化(InnoDB锁问题排查与解决)

    1.概述 前面章节之所以介绍那么多锁的知识点和示例,其实最终目的就是为了排查与解决死锁的问题,下面我们把之前学过锁知识重温与补充一遍,然后再通过例子演示下如果排查与解决死锁. 2.前期准备 ●数据库事 ...

  7. (7)MySQL进阶篇SQL优化(InnoDB锁-事务隔离级别 )

    1.概述 在我们在学习InnoDB锁知识点之前,我觉得有必要让大家了解它的背景知识,因为这样才能让我们更系统地学习好它.InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION ...

  8. (8)MySQL进阶篇SQL优化(InnoDB锁-共享锁、排他锁与意向锁)

    1.锁的分类 锁(Locking)是数据库在并发访问时保证数据一致性和完整性的主要机制.之前MyISAM锁章节已经讲过锁分类,而InnoDB锁按照粒度分为锁定整个表的表级锁(table-level l ...

  9. (9)MySQL进阶篇SQL优化(InnoDB锁-记录锁)

    1.概述 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点意味着:只有通过索引条件检索 ...

随机推荐

  1. (转载)ACM训练计划,先过一遍基础再按此拼搏吧!!!!

    ACM大量习题题库 ACM大量习题题库 现在网上有许多题库,大多是可以在线评测,所以叫做Online Judge.除了USACO是为IOI准备外,其余几乎全部是大学的ACM竞赛题库. USACO ht ...

  2. 【翻译】checkbox的第三种状态

    checkbox只有两种值:选中(checked)或未选中(unchecked).它可以有任何值,但是表单提交时checkbox的值只能是checked或unchecked.它的默认值是uncheck ...

  3. MyBatis 从浅入深 随笔整理

    MyBatis? archetypeCatalog = internal 本文档单独出现的_parameter都标识为变量名 一.三个基本要素: 核心接口和类 MyBatis 核心配置文件 SQL映射 ...

  4. gson Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path

    返回数据解析错误 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT ...

  5. [AHOI2013]作业

    [AHOI2013]作业 题目大意: 给定一个长度为\(n(n\le10^5)\)的数列\(A(1\le A_i\le n)\).\(m(m\le10^6)\)次询问,每次询问区间\([l,r]\)内 ...

  6. markdown编辑器使用指南

    欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接 ...

  7. 使用 IntraWeb (8) - 系统模板

    我们可以自定义系统错误模板, 编辑 IWError.html 放到模板文件夹后, 它将替换默认的模板. {在主页面, 这是要模拟一个系统错误} procedure TIWForm1.IWButton1 ...

  8. VGA Signal Timing

    VGA Signal Timing 640 x 350 VGA 640x350@70 Hz (pixel clock 25.175 MHz) VESA 640x350@85 Hz (pixel clo ...

  9. 【Go命令教程】6. go doc 与 godoc

    go doc 命令可以打印附于Go语言程序 实体 上的文档.我们可以通过把程序实体的标识符作为该命令的参数来达到查看其文档的目的. 插播:所谓 Go语言的 程序实体,是指变量.常量.函数.结构体以及接 ...

  10. 【k8s】搭建步骤

    搭建步骤 基础概念:https://www.cnblogs.com/sxdcgaq8080/p/10640879.html ====================================== ...