问题 需要Mysql死锁解释


我通过“SHOW INNODB STATUS”收到以下死锁日志。有人可以解释为什么交易被中止了吗?似乎事务2持有锁,但是也被卡住请求相同的锁(“等待”部分除外),这在事务1需要它时也会导致死锁。

=====================================                                                                                                                                                                          
091205  6:25:01 INNODB MONITOR OUTPUT                                                                                                                                                                          
=====================================                                                                                                                                                                          
Per second averages calculated from the last 39 seconds                                                                                                                                                        
----------                                                                                                                                                                                                     
SEMAPHORES                                                                                                                                                                                                     
----------                                                                                                                                                                                                     
OS WAIT ARRAY INFO: reservation count 233826, signal count 229982                                                                                                                                              
Mutex spin waits 0, rounds 1569878, OS waits 4740                                                                                                                                                              
RW-shared spins 517345, OS waits 227127; RW-excl spins 4390, OS waits 1945                                                                                                                                     
------------------------                                                                                                                                                                                       
LATEST DETECTED DEADLOCK                                                                                                                                                                                       
------------------------                                                                                                                                                                                       
091205  6:19:35                                                                                                                                                                                                
*** (1) TRANSACTION:                                                                                                                                                                                           
TRANSACTION 0 479286429, ACTIVE 0 sec, process no 17618, OS thread id 2963139472 fetching rows                                                                                                                 
mysql tables in use 1, locked 1                                                                                                                                                                                
LOCK WAIT 176 lock struct(s), heap size 11584                                                                                                                                                                  
MySQL thread id 330396, query id 97467367 64-71-26-218.static.wiline.com 64.71.26.218 autotaggeruser Sorting result                                                                                            
SELECT api_key,completed,compute_units,created,deleted,flags,func_name,group_id,hostname,is_meta,jid,label,language,num_children,parent_ujid,priority,process_id,restartable,status,type,uid,ujid,version,wid FROM jobs WHERE status='new' and is_meta=0 ORDER BY priority asc,jid asc FOR UPDATE                                                                                                                             
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:                                                                                                                                                                   
RECORD LOCKS space id 0 page no 17549 n bits 128 index `PRIMARY` of table `takeyourorder/jobs` trx id 0 479286429 lock_mode X waiting                                                               
Record lock, heap no 61 PHYSICAL RECORD: n_fields 26; compact format; info bits 0                                                                                                                              
0: len 8; hex 800000000000277c; asc       '|;; 1: len 6; hex 00001c915499; asc     T ;; 2: len 7; hex 00000006e21e2a; asc       *;; 3: len 8; hex 8000000000000002; asc         ;; 4: len 8; hex 8000000000000845; asc        E;; 5: SQL NULL; 6: len 8; hex 8000000000002773; asc       's;; 7: len 1; hex 80; asc  ;; 8: len 8; hex 8000000000000002; asc         ;; 9: len 16; hex 636f72656f66746865627261696e2d75; asc coreofthebrain-u;; 10: len 4; hex 80000eb8; asc     ;; 11: len 1; hex 01; asc  ;; 12: len 30; hex 322e362e32202872656c6561736532362d6d61696e742c20417072203139; asc 2.6.2 (release26-maint, Apr 19;...(truncated); 13: len 30; hex 5f5f6d61696e5f5f2e3c6c616d6264613e206174203c737464696e3e3a31; asc __main__.<lambda> at <stdin>:1;; 14: len 5; hex 8000000001; asc      ;; 15: len 0; hex ; asc ;; 16: len 4; hex 80000000; asc     ;; 17: len 4; hex 80000005; asc     ;; 18: len 4; hex 4b19fb58; asc K  X;; 19: len 4; hex 4b19fb77; asc K  w;; 20: len 1; hex 07; asc  ;; 21: len 1; hex 80; asc  ;; 22: len 4; hex 80000000; asc     ;; 23: len 4; hex 80000000; asc     ;; 24: len 1; hex 80; asc  ;; 25: len 4; hex 80001415; asc     ;;                                                                                                            

*** (2) TRANSACTION:
TRANSACTION 0 479286425, ACTIVE 0 sec, process no 17618, OS thread id 2971134864 starting index read, thread declared inside InnoDB 500
mysql tables in use 1, locked 1                                                                                                        
7 lock struct(s), heap size 1024, undo log entries 3                                                                                   
MySQL thread id 330430, query id 97467371 64-71-26-218.static.wiline.com 64.71.26.218 autotaggeruser Updating                          
UPDATE jobs SET status='done' WHERE jid=10099                                                                                          
*** (2) HOLDS THE LOCK(S):                                                                                                             
RECORD LOCKS space id 0 page no 17549 n bits 128 index `PRIMARY` of table `takeyourorder/jobs` trx id 0 479286425 lock_mode X locks rec but not gap
Record lock, heap no 61 PHYSICAL RECORD: n_fields 26; compact format; info bits 0                                                                             
0: len 8; hex 800000000000277c; asc       '|;; 1: len 6; hex 00001c915499; asc     T ;; 2: len 7; hex 00000006e21e2a; asc       *;; 3: len 8; hex 8000000000000002; asc         ;; 4: len 8; hex 8000000000000845; asc        E;; 5: SQL NULL; 6: len 8; hex 8000000000002773; asc       's;; 7: len 1; hex 80; asc  ;; 8: len 8; hex 8000000000000002; asc         ;; 9: len 16; hex 636f72656f66746865627261696e2d75; asc coreofthebrain-u;; 10: len 4; hex 80000eb8; asc     ;; 11: len 1; hex 01; asc  ;; 12: len 30; hex 322e362e32202872656c6561736532362d6d61696e742c20417072203139; asc 2.6.2 (release26-maint, Apr 19;...(truncated); 13: len 30; hex 5f5f6d61696e5f5f2e3c6c616d6264613e206174203c737464696e3e3a31; asc __main__.<lambda> at <stdin>:1;; 14: len 5; hex 8000000001; asc      ;; 15: len 0; hex ; asc ;; 16: len 4; hex 80000000; asc     ;; 17: len 4; hex 80000005; asc     ;; 18: len 4; hex 4b19fb58; asc K  X;; 19: len 4; hex 4b19fb77; asc K  w;; 20: len 1; hex 07; asc  ;; 21: len 1; hex 80; asc  ;; 22: len 4; hex 80000000; asc     ;; 23: len 4; hex 80000000; asc     ;; 24: len 1; hex 80; asc  ;; 25: len 4; hex 80001415; asc     ;;                                                                                                            

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 17548 n bits 144 index `PRIMARY` of table `takeyourorder/jobs` trx id 0 479286425 lock_mode X locks rec but not gap waiting
Record lock, heap no 73 PHYSICAL RECORD: n_fields 26; compact format; info bits 0                                                                                     
0: len 8; hex 8000000000002773; asc       's;; 1: len 6; hex 00001c9151f5; asc     Q ;; 2: len 7; hex 800000003c0110; asc     <  ;; 3: len 8; hex 8000000000000002; asc         ;; 4: len 8; hex 800000000000083d; asc        =;; 5: SQL NULL; 6: SQL NULL; 7: len 1; hex 81; asc  ;; 8: len 8; hex 8000000000000002; asc         ;; 9: len 16; hex 636f72656f66746865627261696e2d75; asc coreofthebrain-u;; 10: len 4; hex 80000eb8; asc     ;; 11: len 1; hex 01; asc  ;; 12: len 30; hex 322e362e32202872656c6561736532362d6d61696e742c20417072203139; asc 2.6.2 (release26-maint, Apr 19;...(truncated); 13: len 30; hex 5f5f6d61696e5f5f2e3c6c616d6264613e206174203c737464696e3e3a31; asc __main__.<lambda> at <stdin>:1;; 14: len 5; hex 8000000001; asc      ;; 15: len 0; hex ; asc ;; 16: len 4; hex 80000000; asc     ;; 17: len 4; hex 80000005; asc     ;; 18: len 4; hex 4b19fb58; asc K  X;; 19: SQL NULL; 20: len 1; hex 02; asc  ;; 21: len 1; hex 80; asc  ;; 22: len 4; hex 80000014; asc     ;; 23: len 4; hex 80000000; asc     ;; 24: len 1; hex 80; asc  ;; 25: SQL NULL;                                                                                                                                                                                          

*** WE ROLL BACK TRANSACTION (1)

11117
2017-12-05 07:55


起源



答案:


第一步是确定两个查询是什么:

SELECT api_key,已完成, compute_units,创建,删除,标志, func_name,group_id,主机名, is_meta,jid,标签,语言, num_childrenparent_ujid, 优先, process_id,restartable,status,type,uid,ujid,version,wid FROM jobs WHERE status ='new'和is_meta = 0 ORDER BY priority asc,jid asc 更新

..和:

UPDATE jobs SET status ='done'WHEREid = 10099

第一个是SELECT,第二个是UPDATE。但关键是 FOR UPDATE 在SELECT的末尾,我用粗体强调。

FOR UPDATE 语法用于锁定读取 - 您可以 在这里阅读有关它的文档。该 MySQL死锁文档 建议使用 READ COMMITTED 如果遇到像这些问题的锁定问题。

显示INNODB状态走过


6
2017-12-05 08:19



感谢您及时的回复。我确实识别了两个查询,我确实看到更新与更新冲突。我的问题更多的是以下几点:为什么UPDATE查询不能完成?它的交易已经持有相应的锁。此外,READ COMMITTED不是一个可能的解决方案,因为我不能从SELECT查询中获得陈旧的结果。 - BrainCore
@BrainCore: Locks set by LOCK IN SHARE MODE and FOR UPDATE reads are released when the transaction is committed or rolled back. - OMG Ponies
@OMG小马:我过去曾无数次见过这句话。这听起来是否合理:事务2在表上获得了这些锁“lock_mode X锁定rec但不是间隙”。事务1然后​​等待该表的锁“lock_mode X waiting”,它们由事务2拥有。然后,事务2执行另一个查询,该查询需要“lock_mode X锁定rec而不是间隙等待”(正在等待实际的锁类型?) 。既然它已经有了这些锁,为什么它不仅仅使用它们呢?它是否“陷入”事务1的请求,ala FIFO队列? - BrainCore
@BrainCore:确切地说 - 事务2在事务1的请求后面“卡住”,即一个FIFO队列。 - OMG Ponies


答案:


第一步是确定两个查询是什么:

SELECT api_key,已完成, compute_units,创建,删除,标志, func_name,group_id,主机名, is_meta,jid,标签,语言, num_childrenparent_ujid, 优先, process_id,restartable,status,type,uid,ujid,version,wid FROM jobs WHERE status ='new'和is_meta = 0 ORDER BY priority asc,jid asc 更新

..和:

UPDATE jobs SET status ='done'WHEREid = 10099

第一个是SELECT,第二个是UPDATE。但关键是 FOR UPDATE 在SELECT的末尾,我用粗体强调。

FOR UPDATE 语法用于锁定读取 - 您可以 在这里阅读有关它的文档。该 MySQL死锁文档 建议使用 READ COMMITTED 如果遇到像这些问题的锁定问题。

显示INNODB状态走过


6
2017-12-05 08:19



感谢您及时的回复。我确实识别了两个查询,我确实看到更新与更新冲突。我的问题更多的是以下几点:为什么UPDATE查询不能完成?它的交易已经持有相应的锁。此外,READ COMMITTED不是一个可能的解决方案,因为我不能从SELECT查询中获得陈旧的结果。 - BrainCore
@BrainCore: Locks set by LOCK IN SHARE MODE and FOR UPDATE reads are released when the transaction is committed or rolled back. - OMG Ponies
@OMG小马:我过去曾无数次见过这句话。这听起来是否合理:事务2在表上获得了这些锁“lock_mode X锁定rec但不是间隙”。事务1然后​​等待该表的锁“lock_mode X waiting”,它们由事务2拥有。然后,事务2执行另一个查询,该查询需要“lock_mode X锁定rec而不是间隙等待”(正在等待实际的锁类型?) 。既然它已经有了这些锁,为什么它不仅仅使用它们呢?它是否“陷入”事务1的请求,ala FIFO队列? - BrainCore
@BrainCore:确切地说 - 事务2在事务1的请求后面“卡住”,即一个FIFO队列。 - OMG Ponies


我不是百分百肯定,但我相信他们不是“同一个锁”。

* (1)等待此锁定被授予:记录锁定空间id 0页号17549 n位128索引 PRIMARY 的表 takeyourorder/jobs   trx id 0 479286429 lock_mode X waiting记录锁,堆没有61   物理记录:n_fields 26;紧凑格式;信息位0

* (2)HOLDS THE LOCK(S):RECORD LOCKS space id 0 page no 17549 n bits 128 index PRIMARY 的表 takeyourorder/jobs trx id 0   479286425 lock_mode X锁定rec而不是gap记录锁定,堆没有61   物理记录:n_fields 26;紧凑格式;信息位0

* (2)等待此锁定被授予:RECORD LOCKS空格id 0页号17548 n位144索引 PRIMARY 的表 takeyourorder/jobs   trx id 0 479286425 lock_mode X锁定rec而不是间隙等待记录   锁定,堆积73物理记录:n_fields 26;紧凑格式;信息   位0

Tx(2)保持“堆没有61”记录锁定并且正在等待“堆没有73”记录锁定。 Tx(1)正在等待“堆没有61”。日志不会告诉谁持有“堆没有73”,但可能只是“SHOW ENGINE INNODB STATUS”的限制。 您可以确认将通过简单的死锁方案生成类似的日志。


4
2017-10-17 06:56