为什么意图专用锁与MySQL中的Intension Exclusive Lock兼容?

时间:2017-11-01 03:52:11

标签: mysql locking

enter image description here

根据MySQL 5.7中的参考SELECT ... LOCK IN SHARE MODE sets an IS lock and SELECT ... FOR UPDATE sets an IX lock.

我真的很困惑IX与IX兼容。它的意思是什么?

另一方面,我在下面尝试过:

Sess1 db> BEGIN;
          SELECT * FROM t WHERE id = 1 FOR UPDATE;   -- id is a primary key
Sess2 db> BEGIN;
          SELECT * FROM t WHERE id = 1 FOR UPDATE;  -- Oops, it's blocking!

Sess1 db> BEGIN;
          SELECT * FROM t FOR UPDATE;    
Sess2 db> BEGIN;
          SELECT * FROM t WHERE id = 1 FOR UPDATE;  -- Oops, blocking too!

作为Uppon,如果我不误解SELECT .. FOR UPDATE; is an IX lock,IX会在同一个索引上阻止其他IX。

那么,如何理解IX与MySQL中的IX兼容?

或者如何理解MySQL 5.7参考(https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html

中的SELECT ... LOCK IN SHARE MODE sets an IS lock and SELECT ... FOR UPDATE sets an IX lock.

2 个答案:

答案 0 :(得分:1)

在您显示的示例中,它是冲突的X锁。

更新:MySQL工程师提醒我,IS / IX锁在存储引擎层实现。 MySQL有一个古怪的体系结构,它以独立于存储的方式实现一些语义,但是将一些其他操作委托给存储引擎。而存储引擎也可以自己做一些事情,它们在SQL层没有模拟。

IS / IX锁仅在InnoDB存储引擎中实现。所以他们是一个特殊的野兽,我不应该将它们与用LOCK TABLES获得的表级锁进行比较。如果有的话,目前还不清楚它们是如何相互作用的。

我的原始答案如下:无论好坏......

IX锁用于所有实际目的是表级锁。允许多个会话同时获取IX锁定是可以的,因为它们可能不会在行级别发生冲突。如果他们这样做,他们各自的X锁将解决该冲突。但如果实际更新不同的行,那就不会有问题。

但是IX锁与其他真实表锁冲突,例如由LOCK TABLESALTER TABLEDROP TABLE创建的锁。例如,您不希望任何人在ALTER TABLE期间执行行级更改,反之亦然:ALTER TABLE必须等待保存IX锁的所有事务完成。

重新评论:

试试这个:

session1> LOCK TABLES MyTable READ;

session2> SELECT * FROM MyTABLE;                    /* no problem */
session2> SELECT * FROM MyTABLE LOCK IN SHARE MODE; /* no problem */
session2> SELECT * FROM MyTABLE FOR UPDATE;         /* waits for lock */

与:比较:

session1> LOCK TABLES MyTable WRITE;

session2> SELECT * FROM MyTABLE;                    /* no problem */
session2> SELECT * FROM MyTABLE LOCK IN SHARE MODE; /* waits for lock */
session2> SELECT * FROM MyTABLE FOR UPDATE;         /* waits for lock */

因此:

答案 1 :(得分:0)

  1. 图片上的锁兼容性表用于相同级别的锁。(例如,表IX锁与另一表IX锁兼容)
  2. 要获取低级别的锁(例如,行级别的X / S锁),您需要获取较高级别的故意锁(例如,表IX锁)

一个表级IX锁与另一个表级IX锁兼容,但与表级X / S锁不兼容。(您可以通过sql“锁定表some_table读/写”来获取表S / X锁)

当请求行级X / S锁(例如,选择...以进行更新)时,它实际上是在执行
请求写记录的命令:
---> IX(表格); X(记录)
以相反的顺序释放。