[英]MySql InnoDB Repeatable Read Unexpected behavior of locks
As I know, innoDB use mechanism of consistent non blocking read, so every transaction works with its own snapshot. 据我所知,innoDB使用一致的非阻塞读取机制,因此每个事务都具有自己的快照。
it is told also in official documentation 在官方文档中也有介绍
A consistent read does not set any locks on the tables it accesses, and therefore other sessions are free to modify those tables at the same time a consistent read is being performed on the table.
一致读取不会在它访问的表上设置任何锁,因此其他会话可以在对该表执行一致读取的同时自由地修改那些表。
But I unexpectedly faced with behavior when classic 'read/update' deadlock appears: 但是当经典的“读取/更新”死锁出现时,我出乎意料地面临着行为:
Isolation level REPEATABLE READ (also is reproduced with READ COMMITTED ) 隔离级别 REPEATABLE READ (也由READ COMMITTED复制)
Transaction 1 reads row ( NOT lock in share mode ). 事务1读取行( 不 锁共享模式 )。
Transaction 2 reads the same row ( ALSO NOT lock in share mode ). 事务2读取同一行(也不要 在共享模式下锁定 )。 then
然后
Transaction 1 tries to update this row. 事务1尝试更新此行。
Transaction 2 also tries to update this row. 事务2也尝试更新此行。
After last step, innoDB detects deadlock (there is LATEST DETECTED DEADLOCK below): ---------------- 2017-03-31 16:07:03 0x1f58 *** (1) TRANSACTION: TRANSACTION 413412, ACTIVE 20 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 9 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 3 MySQL thread id 33, OS thread handle 8148, query id 102005 localhost 127.0.0.1 root updating 在最后一步之后,innoDB检测到死锁(下面有最新检测到的死锁):---------------- 2017-03-31 16:07:03 0x1f58 ***(1)事务:TRANSACTION 413412,正在活动的20秒开始索引正在读取使用中的mysql表1,已锁定1 LOCK WAIT 9锁定结构,堆大小1136,6行锁定,撤消日志条目3 MySQL线程id 33,OS线程句柄8148,查询ID 102005 localhost 127.0.0.1根更新
/* update Order */ update `Order` set ... <fields to update>
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2151 page no 709 n bits 88 index PRIMARY of table `ooapp2`.`order` trx id 413412 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 54; compact format; info bits 0
*** (2) TRANSACTION:
TRANSACTION 413413, ACTIVE 11 sec starting index read
mysql tables in use 1, locked 1
9 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 3
MySQL thread id 28, OS thread handle 8024, query id 102008 localhost 127.0.0.1 root updating
/* update Order */ update `Order` set ...<fields to update>
*** (2) **HOLDS THE LOCK(S):**
RECORD LOCKS space id 2151 page no 709 n bits 88 index PRIMARY of table `ooapp2`.`order` trx id 413413 lock mode S locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 54; compact format; info bits 0
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2151 page no 709 n bits 88 index PRIMARY of table `ooapp2`.`order` trx id 413413 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 54; compact format; info bits 0
*** WE ROLL BACK TRANSACTION (2)
I can't understand, what happens, why Transaction 2 我不明白,会发生什么,为什么交易2
HOLDS THE LOCK(S)
持有锁
so if innoDB nevertheless not use Consistent Read with snapshot and sets S-locks this does not correspond to the fact that is written in official manual. 因此,如果innoDB仍不对快照使用一致性读取并设置S锁,则这与官方手册中所写的事实不符。
Don't do that. 不要那样做 If you might be updating a row, but meanwhile need the value, use
SELECT ... FOR UPDATE;
如果您可能正在更新一行,但同时需要该值,请使用
SELECT ... FOR UPDATE;
. 。 Just do that, and forget about
tx_isolation
. 只需执行此操作,就不必再担心
tx_isolation
。 Normally, this will turn a Deadlock into a delay. 通常,这会将死锁变成延迟。 (See
innodb_lock_wait_timeout
, which defaults to an over-generous 50 seconds.) (请参阅
innodb_lock_wait_timeout
,它默认为过分的50秒。)
Also, when you do get a Deadlock, re-run the entire transaction. 此外,当你得到一个僵局,重新运行整个事务。 Deadlocks will happen no matter how hard you try to avoid them.
无论您多么努力避免死锁,都会发生死锁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.