一、自我介绍

20年毕业,双非本,先后就职于金蝶、虾皮、快手,从事电商后端开发,北漂中。来戳我交个朋友~


二、一次死锁排查

执行show engine innodb status;后,将Status字段的关键信息截取出来(有局限性,Holds The Locks不一定是这条sql加的):


LATEST DETECTED DEADLOCK


2022-04-20 13:53:45
*** (1) TRANSACTION:
TRANSACTION 42111123345124, 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)(获取了两个行锁-S) MySQL thread id 3443, OS thread handle 13946546874344, query id 25911 Sending data
SELECT ​​​id​​​,​​item_id,​​​​shop_id​​​,​​region_id, channel_id​​​​ FROM ​​item_test_tab​​​ WHERE ((​​item_id​​​=?) AND (​​shop_id​​​=?)) AND (​​region_id​​​=?)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 24 page no 3 n bits 96 index PRIMARY of table ​​​item_test_tab​​​ trx id 423413945844 lock mode S locks rec but not gap waiting(在等待primary表的​​lock mode S locks rec but not gap​​​,即 record lock-S)
Record lock

(事务一没有显示HOLDS THE LOCK,如果推断不出它获得的锁,可以自己在DBeaver上执行事务一然后看data_locks表会产生哪些锁)

*** (2) TRANSACTION:
TRANSACTION 177226, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
7 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 1 MySQL thread id 3395, OS thread handle 139645483345416, query id 25731 root updating
DELETE FROM ​​​item_test_tab​​​ WHERE (((​​item_id​​​=?) AND (​​shop_id​​​=?)) AND (​​region_id​​​=?)) AND (​​channel_id​​​ IN (?,?))
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 24 page no 3 n bits 72 index PRIMARY of table ​​​item_test_tab​​​ trx id 17726 lock_mode X locks rec but not gap
Record lock(持有primary表的​​​lock mode X locks rec but not gap​​​,即record lock-X)
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 24 page no 4 n bits 72 index idx_shop_id_item_id_channel_id of table ​​​item_test_tab​​​ trx id 17726 lock_mode X locks rec but not gap waiting
Record lock(在等待index表的​​​lock mode X locks rec but not gap​​,即record lock)

*** WE ROLL BACK TRANSACTION (1)

助读:

lock mode S/X rec but not gap 是record lock,lock mode S/X 是next-keys lock,lock_mode S/X locks gap before rec 是gap lock,lock mode X locks gap before rec insert intention / lock_mode X insert intention 是插入意向锁

结论:

select获得了索引表的record lock-S然后回表等待主表的record lock-S;delete获得了主表的record lock-X然后等待索引表的record lock-X,死锁。

解决:
  1. 不用select * .. 利用索引覆盖避免回表。
  2. select ignore index禁止使用索引,直接查主表



三、立一个flag

  1. 不熬夜,早起健身,五一假期前减10斤
  2. 今年把《数据密集型应用系统设计》看完