Description:
i found mysql will report deadlock when i 'select for update' even ‘update’ with same record in concurrency thread, with the error status of innodb:
=====================================
2018-03-23 15:22:19 0x7f0824272700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 16 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 249 srv_active, 0 srv_shutdown, 1559184 srv_idle
srv_master_thread log flush and writes: 1558877
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 460
OS WAIT ARRAY INFO: signal count 376
RW-shared spins 0, rounds 441, OS waits 193
RW-excl spins 0, rounds 1371, OS waits 25
RW-sx spins 1, rounds 28, OS waits 0
Spin rounds per wait: 441.00 RW-shared, 1371.00 RW-excl, 28.00 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-03-23 15:21:54 0x7f08241df700
*** (1) TRANSACTION:
TRANSACTION 349110, ACTIVE 0 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 143, OS thread handle 139672943212288, query id 460994 10.5.17.15 loanuser statistics
select
ID, NAME
from t_deadlock
where ID = 'T1-9' for update
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 118 page no 3 n bits 80 index PRIMARY of table "test"."t_deadlock" trx id 349110 lock_mode X locks rec but not gap waiting
Record lock, heap no 11 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 54312d39; asc T1-9;;
1: len 6; hex 0000000553b4; asc S ;;
2: len 7; hex 3a0000021701fb; asc : ;;
3: len 1; hex 47; asc G;;
*** (2) TRANSACTION:
TRANSACTION 349111, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 141, OS thread handle 139672942409472, query id 460996 10.5.17.15 loanuser statistics
select
ID, NAME
from t_deadlock
where ID = 'T1-9' for update
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 118 page no 3 n bits 80 index PRIMARY of table "test"."t_deadlock" trx id 349111 lock mode S locks rec but not gap
Record lock, heap no 11 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 54312d39; asc T1-9;;
1: len 6; hex 0000000553b4; asc S ;;
2: len 7; hex 3a0000021701fb; asc : ;;
3: len 1; hex 47; asc G;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 118 page no 3 n bits 80 index PRIMARY of table "loan"."t_deadlock" trx id 349111 lock_mode X locks rec but not gap waiting
Record lock, heap no 11 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 54312d39; asc T1-9;;
1: len 6; hex 0000000553b4; asc S ;;
2: len 7; hex 3a0000021701fb; asc : ;;
3: len 1; hex 47; asc G;;
*** WE ROLL BACK TRANSACTION (2)
------------
TRANSACTIONS
------------
Trx id counter 349120
Purge done for trx's n:o < 349120 undo n:o < 0 state: running but idle
History list length 46
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421148215175928, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421148215175008, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,
ibuf aio reads:, log i/o's:, sync i/o's:
Pending flushes (fsync) log: 0; buffer pool: 0
1693 OS file reads, 2440 OS file writes, 1097 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.81 writes/s, 0.62 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
insert 0, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 0
Hash table size 34673, node heap has 0 buffer(s)
Hash table size 34673, node heap has 0 buffer(s)
Hash table size 34673, node heap has 1 buffer(s)
Hash table size 34673, node heap has 0 buffer(s)
Hash table size 34673, node heap has 2 buffer(s)
Hash table size 34673, node heap has 3 buffer(s)
Hash table size 34673, node heap has 2 buffer(s)
Hash table size 34673, node heap has 0 buffer(s)
0.19 hash searches/s, 0.56 non-hash searches/s
---
LOG
---
Log sequence number 186437447
Log flushed up to 186437447
Pages flushed up to 186437447
Last checkpoint at 186437438
0 pending log flushes, 0 pending chkp writes
858 log i/o's done, 0.38 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 137428992
Dictionary memory allocated 1833906
Buffer pool size 8191
Free buffers 6459
Database pages 1724
Old database pages 639
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 1613, created 111, written 1469
0.00 reads/s, 0.00 creates/s, 0.37 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1724, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
0 read views open inside InnoDB
Process ID=990, Main thread ID=139672864941824, state: sleeping
Number of rows inserted 44210, updated 197, deleted 0, read 958895
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================
How to repeat:
use multi-thread 'select for update' and update a record with same key(primary or unique key)
Suggested fix:
i don't understand why use S locker first when 'select for update' or 'update', maybe for other connection to read share, but i think the X locker need to lock at the point S locker locking, or the X locker could insert the locker order in first when the connection hold the S lock?
Description: i found mysql will report deadlock when i 'select for update' even ‘update’ with same record in concurrency thread, with the error status of innodb: ===================================== 2018-03-23 15:22:19 0x7f0824272700 INNODB MONITOR OUTPUT ===================================== Per second averages calculated from the last 16 seconds ----------------- BACKGROUND THREAD ----------------- srv_master_thread loops: 249 srv_active, 0 srv_shutdown, 1559184 srv_idle srv_master_thread log flush and writes: 1558877 ---------- SEMAPHORES ---------- OS WAIT ARRAY INFO: reservation count 460 OS WAIT ARRAY INFO: signal count 376 RW-shared spins 0, rounds 441, OS waits 193 RW-excl spins 0, rounds 1371, OS waits 25 RW-sx spins 1, rounds 28, OS waits 0 Spin rounds per wait: 441.00 RW-shared, 1371.00 RW-excl, 28.00 RW-sx ------------------------ LATEST DETECTED DEADLOCK ------------------------ 2018-03-23 15:21:54 0x7f08241df700 *** (1) TRANSACTION: TRANSACTION 349110, ACTIVE 0 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 143, OS thread handle 139672943212288, query id 460994 10.5.17.15 loanuser statistics select ID, NAME from t_deadlock where ID = 'T1-9' for update *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 118 page no 3 n bits 80 index PRIMARY of table "test"."t_deadlock" trx id 349110 lock_mode X locks rec but not gap waiting Record lock, heap no 11 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 4; hex 54312d39; asc T1-9;; 1: len 6; hex 0000000553b4; asc S ;; 2: len 7; hex 3a0000021701fb; asc : ;; 3: len 1; hex 47; asc G;; *** (2) TRANSACTION: TRANSACTION 349111, ACTIVE 0 sec starting index read mysql tables in use 1, locked 1 3 lock struct(s), heap size 1136, 2 row lock(s) MySQL thread id 141, OS thread handle 139672942409472, query id 460996 10.5.17.15 loanuser statistics select ID, NAME from t_deadlock where ID = 'T1-9' for update *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 118 page no 3 n bits 80 index PRIMARY of table "test"."t_deadlock" trx id 349111 lock mode S locks rec but not gap Record lock, heap no 11 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 4; hex 54312d39; asc T1-9;; 1: len 6; hex 0000000553b4; asc S ;; 2: len 7; hex 3a0000021701fb; asc : ;; 3: len 1; hex 47; asc G;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 118 page no 3 n bits 80 index PRIMARY of table "loan"."t_deadlock" trx id 349111 lock_mode X locks rec but not gap waiting Record lock, heap no 11 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 4; hex 54312d39; asc T1-9;; 1: len 6; hex 0000000553b4; asc S ;; 2: len 7; hex 3a0000021701fb; asc : ;; 3: len 1; hex 47; asc G;; *** WE ROLL BACK TRANSACTION (2) ------------ TRANSACTIONS ------------ Trx id counter 349120 Purge done for trx's n:o < 349120 undo n:o < 0 state: running but idle History list length 46 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 421148215175928, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421148215175008, not started 0 lock struct(s), heap size 1136, 0 row lock(s) -------- FILE I/O -------- I/O thread 0 state: waiting for completed aio requests (insert buffer thread) I/O thread 1 state: waiting for completed aio requests (log thread) I/O thread 2 state: waiting for completed aio requests (read thread) I/O thread 3 state: waiting for completed aio requests (read thread) I/O thread 4 state: waiting for completed aio requests (read thread) I/O thread 5 state: waiting for completed aio requests (read thread) I/O thread 6 state: waiting for completed aio requests (write thread) I/O thread 7 state: waiting for completed aio requests (write thread) I/O thread 8 state: waiting for completed aio requests (write thread) I/O thread 9 state: waiting for completed aio requests (write thread) Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] , ibuf aio reads:, log i/o's:, sync i/o's: Pending flushes (fsync) log: 0; buffer pool: 0 1693 OS file reads, 2440 OS file writes, 1097 OS fsyncs 0.00 reads/s, 0 avg bytes/read, 0.81 writes/s, 0.62 fsyncs/s ------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 1 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 2 buffer(s) Hash table size 34673, node heap has 3 buffer(s) Hash table size 34673, node heap has 2 buffer(s) Hash table size 34673, node heap has 0 buffer(s) 0.19 hash searches/s, 0.56 non-hash searches/s --- LOG --- Log sequence number 186437447 Log flushed up to 186437447 Pages flushed up to 186437447 Last checkpoint at 186437438 0 pending log flushes, 0 pending chkp writes 858 log i/o's done, 0.38 log i/o's/second ---------------------- BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 137428992 Dictionary memory allocated 1833906 Buffer pool size 8191 Free buffers 6459 Database pages 1724 Old database pages 639 Modified db pages 0 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 0, not young 0 0.00 youngs/s, 0.00 non-youngs/s Pages read 1613, created 111, written 1469 0.00 reads/s, 0.00 creates/s, 0.37 writes/s Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000 Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 1724, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0] -------------- ROW OPERATIONS -------------- 0 queries inside InnoDB, 0 queries in queue 0 read views open inside InnoDB Process ID=990, Main thread ID=139672864941824, state: sleeping Number of rows inserted 44210, updated 197, deleted 0, read 958895 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s ---------------------------- END OF INNODB MONITOR OUTPUT ============================ How to repeat: use multi-thread 'select for update' and update a record with same key(primary or unique key) Suggested fix: i don't understand why use S locker first when 'select for update' or 'update', maybe for other connection to read share, but i think the X locker need to lock at the point S locker locking, or the X locker could insert the locker order in first when the connection hold the S lock?