Deadlock case 6

Source: public account yangyidba


I. Introduction

Deadlock is actually a very interesting and challenging technical problem. Probably every DBA and some development students will encounter it in the course of work. Regarding deadlock, I will continue to write a series of case studies, hoping to help friends who want to understand deadlock.

2. Case analysis

2.1 Environmental description

MySQL 5.6.24 transaction isolation level is RR

create table tx (
  id int not null primary key auto_increment ,
  c1 int not null default 0,
  c2 int not null default 0,
  key idx_c1(c1)
) engine=innodb ;
insert into tx values(24,3,4),(25,3,4),
(26,3,4),(30,5,8);

2.2 Test case

2.3 Deadlock log

----------------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-03-27 15:40:40 0x7f75cafce700
*** (1) TRANSACTION:
TRANSACTION 1850, ACTIVE 20 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 379040, OS thread handle 140143994337024, query id 1521958 localhost root updating
update tx set c2=8 where c1=5
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 27 page no 3 n bits 72 index PRIMARY of table `test`.`tx` trx id 1850 lock_mode X locks rec but not gap waiting
*** (2) TRANSACTION:
TRANSACTION 1849, ACTIVE 32 sec updating or deleting, thread declared inside InnoDB 4999
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 379016, OS thread handle 140143893473024, query id 1521976 localhost root updating
delete from tx where id=30
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 27 page no 3 n bits 72 index PRIMARY of table `test`.`tx` trx id 1849 lock_mode X locks rec but not gap
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 27 page no 5 n bits 72 index idx_c1 of table `test`.`tx` trx id 1849 lock_mode X locks rec but not gap waiting
*** WE ROLL BACK TRANSACTION (1)

2.4 Analyze the deadlock log

The first thing to understand is that applying for a lock on the same field requires queuing.

Secondly, the index idx_c1 in table ty is a non-unique ordinary index. We explain it according to the time sequence of transaction execution, which is easier to understand.

T1: sess2 performs the select for update operation and holds the primary key row lock with record id=30: PRIMARY of table test.tx lock_mode X locks rec but not gap

T2: The sess1 statement update updates c2 through the normal index idx_c1, first obtains the X lock lock_mode X locks rec but not gap of idx_c1 c1=5, and then applies for the row lock corresponding to the primary key id=30, but sess2 already holds the row lock of the primary key , So sess1 waits.

T3: sess2 deletes records based on primary key id=30, and needs to apply for row lock with id=30 and index row lock with c1=5. But sess1 and holding the lock, so index idx_c1 of table test.tx trx id 1849 lock_mode X locks rec but not gap waiting

sess2(delete) waits for sess1(update), sess1(update) waits for sess2(select for update) to wait in a loop, causing deadlock.

The root cause of the deadlock in the RDBMS system can be summarized as: the different transaction locking sequence leads to circular waiting, which leads to deadlock.

2.5 Solution

Modify the update of sess1 to update based on the primary key, that is, update tx set c2=x where id=30 , change the lock mode to sequential lock, apply for the lock of the primary key id, and avoid cross-locking and mutual application for each other’s holdings lock.

Three, summary

The deadlock in the above case is because different sessions compete with each other for the common index idx_c1 and the primary key, which leads to a deadlock due to the loop waiting. When encountering high concurrency updating the same row in the production process, consider avoiding updating through different indexes to avoid deadlock.

Extended reading

The full text is over.

Enjoy MySQL :)

Teacher Ye's "MySQL Core Optimization" class has been upgraded to MySQL 8.0, scan the code to start the journey of MySQL 8.0 practice

Guess you like

Origin blog.csdn.net/n88Lpo/article/details/108806208