当前位置:Gxlcms > 数据库问题 > InnoDB 存储引擎的锁机制

InnoDB 存储引擎的锁机制

时间:2021-07-01 10:21:17 帮助过:2人阅读

Conflict Conflict Conflict Conflict IX Conflict Compatible Conflict Compatible S Conflict Conflict Compatible Compatible IS Conflict Compatible Compatible Compatible

 

 

 

 

 

 

 

 

A lock is granted to a requesting transaction if it is compatible with existing locks, but not if it conflicts with existing locks.

A transaction waits until the conflicting existing lock is released. If a lock request conflicts with an existing lock and cannotbe granted because it would cause deadlock, an error occurs.

因此,除了对整个表的请求(比如,LOCK TABLES ... WRITE)外,意向锁不会阻塞其他的事务。持有意向锁表示持有者正在锁定数据行,或者即将锁定数据行。

deadlock:

A deadlock can occur when the transactions lock rows in multiple tables (through statements such as UPDATE or SELECT ... FOR UPDATE), but in the opposite order. A deadlock can also occur when such statements lock ranges of index records and gaps, with each transaction acquiring some locks but not others due to a timing issue.

索引记录上的锁 - Record Lock

比如,SELECT c1 FOR UPDATE FROM t WHERE c1 = 10;避免其他的事务在t.c1=10的位置进行insert、update和delete操作

record lock始终锁定索引记录,即使一个表没有进行索引定义,对于这种情况,InnoDB创建一个隐藏的聚集索引并使用该索引记录锁定

Cap Lock

比如,SELECT c1 FOR UPDATE FROM t WHERE c1 BETWEEN 10 and 20;会在t.c1在10到20之间的索引记录上加锁,防止其他的事务在t.c1列上插入10到20之间的值

Next-Key Locks

A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.

InnoDB uses next-key locks for searches and index scans, which prevents phantom rows .

Insert Intention Locks

是gap锁的一种。多个事务如果不是在相同的索引范围内插入,则无需等待彼此

测试:

mysql> select * from t2;
+------+
| id   |
+------+
|    1 |
|    5 |
|    8 |
|   11 |
+------+

会话S1                                                         会话S2
mysql> begin;                                                                          
Query OK, 0 rows affected (0.00 sec)                                                   
                                                                                                                                                               
mysql> insert into t2(id) values(7);                 mysql> begin;                                                   
Query OK, 1 row affected (0.00 sec)               Query OK, 0 rows affected (0.00 sec)  

                                                                   mysql> insert into t2(id) values(6);
                                                                   Query OK, 1 row affected (0.00 sec)

                                                                   mysql> insert into t2(id) values(7);
                                                                   Query OK, 1 row affected (0.00 sec)

两个会话在插入的行上获取排他锁前,分别在id为5~8的行记录范围内持有intention locks,但不会阻塞对方,因为行之间没有冲突。

再举一个会话在要插入的行记录上获取排他锁之前获取insert intention lock但被阻塞的例子:

S1在id>5的行持有排它锁。此排它锁包含5~11之间的gap锁

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t2 where id>5 for update;
+------+
| id   |
+------+
|    8 |
|   11 |
+------+

S2上在S1查询出的行范围内插入行记录。会持有insert intention lock,但是会等待排它锁

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2 values(7);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>

InnoDB 存储引擎的锁机制

标签:

人气教程排行