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. 2017 JUST Programming Contest 2.0 题解

    [题目链接] A - On The Way to Lucky Plaza 首先,$n>m$或$k>m$或$k>n$就无解. 设$p = \frac{A}{B}$,$ans = C_{ ...

  2. HTML中元素的定位方式

    初中物理就学过,位置是相对的,要有参照物,因此,所有定位都是相对参照物的定位. position 属性: 规定元素的定位类型,该属性的可选值有static.relative.absolute.fixe ...

  3. 样式加载不出来,浏览器控制台报错:Resource interpreted as Stylesheet but transferred with MIME type text/html

    写登录的时候出现的问题,样式时好时坏,浏览器控制台看到的信息是: Uncaught SyntaxError: Unexpected token <Resource interpreted as ...

  4. poj 3660 传递闭包 **

    题意:题目给出了m对的相对关系,求有多少个排名是确定的. 链接:点我 如果这个点到其他点的关系是确定的,那么这个点就是确定的,注意如果这个点到不了其他点,但其他点能到这个点,那么这个点和其他点的关系是 ...

  5. ROS知识(21)----ROS C++代码格式化

    这里提供两种方法. 第一种方法:clang_format 1.安装clang format sudo apt-get install -y clang-format-3.6 2.从github的ros ...

  6. C#操作sqlite数据库使用SQLiteParameter传递参数

    C# code public void AddIMG_ENTRY(img_entry model) { StringBuilder strSql = new StringBuilder(); strS ...

  7. How to detect the types of executable files

    How to detect the types of executable files type { IMAGE_DOS_HEADER: DOS .EXE header. } IMAGE_DOS_HE ...

  8. gitblit无法安装windows服务或者启动服务失败:Failed creating java

    gitblit解压后,命令行运行installService.cmd之前,需要修改里面的参数,将ARCH修改x86,默认是amd64,我的机器是windows 10 Pro 64位版本,jdk也都是6 ...

  9. 正确识别希捷Backup Plus新睿品1TB正品,杜绝奸商猖獗

    刚刚在百度希捷贴吧发了此贴, 马上被删除, 无奈只能发于个人博客,  望看到的朋友能转载到"合适"位置,让更多的朋友看到. 避免上当. 最近准备买个移动硬盘备份电脑资料,看上了睿品 ...

  10. [Winform]无边框窗口悬浮右下角并可以拖拽移动

    摘要 简单实现了一个这样的功能,程序启动时,窗口悬固定在右下角,并可以通过鼠标拖拽移动. 核心代码块 无边框窗口并不出现在任务栏 //无边框 this.FormBorderStyle = System ...