I am reading a manual about innodb transactions but still, there is lots of unclear stuff to me. For instance, I don't quite understand to the following behaviour:
我正在阅读有关innodb交易的手册,但仍然有很多不清楚的东西给我。例如,我不太了解以下行为:
-- client 1 -- client 2
mysql> create table simple (col int)
engine=innodb;
mysql> insert into simple values(1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into simple values(2);
Query OK, 1 row affected (0.00 sec)
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update simple set col=10 where col=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update simple set col=42 where col=2;
-- blocks
Now, the last update command (in the client 2) waits. I would expect the command to execute because I would suppose only the row 1 is locked. The behaviour is the same even if the second command in the client 2 is insert
. Could anyone describe the locking background behind this example (where and why the locks)?
现在,最后一个更新命令(在客户端2中)等待。我希望命令执行,因为我认为只有第1行被锁定。即使客户端2中的第二个命令是插入,行为也是相同的。任何人都可以描述这个例子背后的锁定背景(锁定的地点和原因)?
3 个解决方案
#1
9
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级别,搜索会在遇到的索引记录上设置共享的下一键锁定。
-
SELECT ... FROM ... LOCK IN SHARE MODE sets shared next-key locks on all index records the search encounters.
SELECT ... FROM ... LOCK IN SHARE MODE在搜索遇到的所有索引记录上设置共享的下一键锁定。
-
For index records the search encounters, SELECT ... FROM ... FOR UPDATE blocks other sessions from doing SELECT ... 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 ...在搜索遇到的每条记录上设置一个独占的下一键锁定。
-
DELETE FROM ... WHERE ... sets an exclusive next-key lock on every record the search encounters.
DELETE FROM ... WHERE ...在搜索遇到的每条记录上设置一个独占的下一键锁定。
-
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在插入的行上设置独占锁。此锁是索引记录锁,而不是下一键锁(即没有间隙锁),并且不会阻止其他会话在插入行之前插入间隙。
InnoDB has several types of record-level locks:
InnoDB有几种类型的记录级锁:
-
Record lock: This is a lock on an index record.
记录锁定:这是对索引记录的锁定。
-
Gap lock: This is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.
间隙锁定:这是锁定索引记录之间的间隙,或锁定在第一个或最后一个索引记录之前的间隙。
-
Next-key lock: This is a combination of a record lock on the index record and a gap lock on the gap before the index record.
下一键锁定:这是索引记录上的记录锁定和索引记录之前的间隙上的间隙锁定的组合。
See More :
查看更多 :
Avoiding the Phantom Problem Using Next-Key Locking
使用下一键锁定避免幻像问题
#2
0
ypercube has it right. Specifically, without a unique index that's used in the condition, it will lock more than the single row being affected.
ypercube说对了。具体来说,如果没有在条件中使用的唯一索引,它将锁定多于受影响的单行。
To see the behavior you expect, change your table creation to this:
要查看您期望的行为,请将表创建更改为:
create table simple (col int unique) ENGINE=InnoDB;
The unique index on the col
field will allow it to lock only the affected row.
col字段上的唯一索引将允许它仅锁定受影响的行。
#3
0
"For index records the search encounters, SELECT ... FROM ... FOR UPDATE blocks other sessions from doing SELECT ... 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或读取某些事务隔离级别。一致读取将忽略任何锁定设置读取视图中存在的记录“
What are those certain locks which can be applied with select for update so that other sessions cannot read locked record?
什么是可以通过选择更新应用的某些锁,以便其他会话无法读取锁定记录?
#1
9
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级别,搜索会在遇到的索引记录上设置共享的下一键锁定。
-
SELECT ... FROM ... LOCK IN SHARE MODE sets shared next-key locks on all index records the search encounters.
SELECT ... FROM ... LOCK IN SHARE MODE在搜索遇到的所有索引记录上设置共享的下一键锁定。
-
For index records the search encounters, SELECT ... FROM ... FOR UPDATE blocks other sessions from doing SELECT ... 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 ...在搜索遇到的每条记录上设置一个独占的下一键锁定。
-
DELETE FROM ... WHERE ... sets an exclusive next-key lock on every record the search encounters.
DELETE FROM ... WHERE ...在搜索遇到的每条记录上设置一个独占的下一键锁定。
-
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在插入的行上设置独占锁。此锁是索引记录锁,而不是下一键锁(即没有间隙锁),并且不会阻止其他会话在插入行之前插入间隙。
InnoDB has several types of record-level locks:
InnoDB有几种类型的记录级锁:
-
Record lock: This is a lock on an index record.
记录锁定:这是对索引记录的锁定。
-
Gap lock: This is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.
间隙锁定:这是锁定索引记录之间的间隙,或锁定在第一个或最后一个索引记录之前的间隙。
-
Next-key lock: This is a combination of a record lock on the index record and a gap lock on the gap before the index record.
下一键锁定:这是索引记录上的记录锁定和索引记录之前的间隙上的间隙锁定的组合。
See More :
查看更多 :
Avoiding the Phantom Problem Using Next-Key Locking
使用下一键锁定避免幻像问题
#2
0
ypercube has it right. Specifically, without a unique index that's used in the condition, it will lock more than the single row being affected.
ypercube说对了。具体来说,如果没有在条件中使用的唯一索引,它将锁定多于受影响的单行。
To see the behavior you expect, change your table creation to this:
要查看您期望的行为,请将表创建更改为:
create table simple (col int unique) ENGINE=InnoDB;
The unique index on the col
field will allow it to lock only the affected row.
col字段上的唯一索引将允许它仅锁定受影响的行。
#3
0
"For index records the search encounters, SELECT ... FROM ... FOR UPDATE blocks other sessions from doing SELECT ... 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或读取某些事务隔离级别。一致读取将忽略任何锁定设置读取视图中存在的记录“
What are those certain locks which can be applied with select for update so that other sessions cannot read locked record?
什么是可以通过选择更新应用的某些锁,以便其他会话无法读取锁定记录?