无法破译innodb状态日志中的死锁


16

我们正在从Microsoft ADO.NET连接器访问MySQL。

有时,我们在innodb状态中看到以下死锁,并且无法确定问题的原因。看起来事务(2)正在等待并持有相同的锁?

------------------------
LATEST DETECTED DEADLOCK
------------------------
110606  5:35:09
*** (1) TRANSACTION:
TRANSACTION 0 45321452, ACTIVE 0 sec, OS thread id 3804 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 368, 1 row lock(s)
    MySQL thread id 84, query id 3265713 localhost 127.0.0.1 famdev Updating
    UPDATE people SET company_id = 1610, name = '<name>', password = '<hash>', temp_password = NULL, reset_password_hash = NULL, email = '<redacted>@yahoo.com', phone = NULL, mobile = '<phone>', iphone_device_id = 'android:<id>-<id>', iphone_device_time = '2011-06-06 05:35:09', last_checkin = '2011-06-06 05:24:42', location_lat = <lat>, location_long = -<lng>, gps_strength = 3296, picture_blob_id = 1190, authority = 1, active = 1, date_created = '2011-04-13 20:21:20', last_login = '2011-06-06 05:35:09', panic_mode = 0, battery_level = NULL, battery_state = NULL WHERE people_id = 3125
    *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
    RECORD LOCKS space id 0 page no 11144 n bits 152 index `PRIMARY` of table `family`.`people` trx id 0 45321452 lock_mode X locks rec but not gap waiting
    Record lock, heap no 12 PHYSICAL RECORD: n_fields 25; compact format; info bits 0
    0: len 8; hex 8000000000000c35; asc        5;; 1: len 6; hex 000002b38ce6; asc       ;; 2: len 7; hex 00000002801f89; asc        ;; 3: len 8; hex 800000000000064a; asc        J;; 4: len 4; hex <data>; asc <name>;; 5: len 30; hex <data>; asc <data>;...(truncated); 6: SQL NULL; 7: SQL NULL; 8: len 16; hex <data>; asc <redacted>@yahoo.com;; 9: SQL NULL; 10: len 10; hex <data>; asc <phone>;; 11: len 30; hex <data>; asc android:<id>;...(truncated); 12: len 8; hex <data>; asc    J]  Z;; 13: len 8; hex <data>; asc    J]  Z;; 14: len 8; hex a39410acaa9b4340; asc       C@;; 15: len 8; hex <data>; asc     m S ;; 16: len 2; hex 8ce0; asc   ;; 17: len 8; hex 80000000000004a6; asc         ;; 18: len 4; hex 80000001; asc     ;; 19: len 1; hex 81; asc  ;; 20: len 8; hex <data>; asc    JR   ;; 21: len 8; hex <data>; asc    J]   ;; 22: len 1; hex 80; asc  ;; 23: SQL NULL; 24: SQL NULL;

    *** (2) TRANSACTION:
    TRANSACTION 0 45321448, ACTIVE 0 sec, OS thread id 3176 starting index read, thread declared inside InnoDB 500
    mysql tables in use 1, locked 1
    5 lock struct(s), heap size 1216, 2 row lock(s), undo log entries 1
    MySQL thread id 85, query id 3265714 localhost 127.0.0.1 famdev Updating
    UPDATE people SET company_id = 1610, name = '<name>', password = '<hash>', temp_password = NULL, reset_password_hash = NULL, email = '<redacted>@yahoo.com', phone = NULL, mobile = '<phone>', iphone_device_id = 'android:<id>-<id>-<id>-<id>', iphone_device_time = '2011-06-06 05:24:42', last_checkin = '2011-06-06 05:35:07', location_lat = <lat>, location_long = -<lng>, gps_strength = 3296, picture_blob_id = 1190, authority = 1, active = 1, date_created = '2011-04-13 20:21:20', last_login = '2011-06-06 05:35:09', panic_mode = 0, battery_level = NULL, battery_state = NULL WHERE people_id = 3125
    *** (2) HOLDS THE LOCK(S):
        RECORD LOCKS space id 0 page no 11144 n bits 152 index `PRIMARY` of table `family`.`people` trx id 0 45321448 lock mode S locks rec but not gap
        Record lock, heap no 12 PHYSICAL RECORD: n_fields 25; compact format; info bits 0
        0: len 8; hex 8000000000000c35; asc        5;; 1: len 6; hex 000002b38ce6; asc       ;; 2: len 7; hex 00000002801f89; asc        ;; 3: len 8; hex 800000000000064a; asc        J;; 4: len 4; hex <data>; asc <name>;; 5: len 30; hex <data>; asc <data>;...(truncated); 6: SQL NULL; 7: SQL NULL; 8: len 16; hex <data>; asc <redacted>@yahoo.com;; 9: SQL NULL; 10: len 10; hex <data>; asc <phone>;; 11: len 30; hex <data>; asc android:<id>;...(truncated); 12: len 8; hex <data>; asc    J]  Z;; 13: len 8; hex <data>; asc    J]  Z;; 14: len 8; hex a39410acaa9b4340; asc       C@;; 15: len 8; hex <data>; asc     m S ;; 16: len 2; hex 8ce0; asc   ;; 17: len 8; hex 80000000000004a6; asc         ;; 18: len 4; hex 80000001; asc     ;; 19: len 1; hex 81; asc  ;; 20: len 8; hex <data>; asc    JR   ;; 21: len 8; hex <data>; asc    J]   ;; 22: len 1; hex 80; asc  ;; 23: SQL NULL; 24: SQL NULL;

        *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
        RECORD LOCKS space id 0 page no 11144 n bits 152 index `PRIMARY` of table `family`.`people` trx id 0 45321448 lock_mode X locks rec but not gap waiting
        Record lock, heap no 12 PHYSICAL RECORD: n_fields 25; compact format; info bits 0
        0: len 8; hex 8000000000000c35; asc        5;; 1: len 6; hex 000002b38ce6; asc       ;; 2: len 7; hex 00000002801f89; asc        ;; 3: len 8; hex 800000000000064a; asc        J;; 4: len 4; hex <data>; asc <name>;; 5: len 30; hex <data>; asc <data>;...(truncated); 6: SQL NULL; 7: SQL NULL; 8: len 16; hex <data>; asc <redacted>@yahoo.com;; 9: SQL NULL; 10: len 10; hex <data>; asc <phone>;; 11: len 30; hex <data>; asc android:<id>;...(truncated); 12: len 8; hex <data>; asc    J]  Z;; 13: len 8; hex <data>; asc    J]  Z;; 14: len 8; hex a39410acaa9b4340; asc       C@;; 15: len 8; hex <data>; asc     m S ;; 16: len 2; hex 8ce0; asc   ;; 17: len 8; hex 80000000000004a6; asc         ;; 18: len 4; hex 80000001; asc     ;; 19: len 1; hex 81; asc  ;; 20: len 8; hex <data>; asc    JR   ;; 21: len 8; hex <data>; asc    J]   ;; 22: len 1; hex 80; asc  ;; 23: SQL NULL; 24: SQL NULL;

        *** WE ROLL BACK TRANSACTION (1)

我们已阅读了有关下一个键锁定的文章,但它似乎不适用于我们,因为我们没有进行选择更新。

更新资料

今天早上,我发现了一个稍有不同的死锁签名,这可能是造成此死锁的根本原因。我将死锁发布为一个单独的问题,以使事情变得简单。如果可以确认另一个问题是原因,请在此处进行更新。


我已经用更多的带宽和吞吐量更新了我的答案。
RolandoMySQLDBA 2011年

我使用有关自动提交的内容更新了答案
RolandoMySQLDBA 2011年

顺便说一句,您对此问题的得分为+1,因为这种类型的问题应使DBA保持警惕。
RolandoMySQLDBA 2011年

Answers:


6

这是我所看到的

我看到三个查询,它们几乎都是相同的。

UPDATE people SET company_id = 1610, name = '<name>', password = '<hash>',
temp_password = NULL, reset_password_hash = NULL, email = '<redacted>@yahoo.com',
phone = NULL, mobile = '<phone>', iphone_device_id = 'android:<id>-<id>',
iphone_device_time = '2011-06-06 05:35:09', last_checkin = '2011-06-06 05:24:42',
location_lat = <lat>, location_long = -<lng>, gps_strength = 3296,
picture_blob_id = 1190,authority = 1, active = 1,
date_created = '2011-04-13 20:21:20',
last_login = '2011-06-06 05:35:09', panic_mode = 0, battery_level = NULL,
battery_state = NULL WHERE people_id = 3125;

差异

交易1

iphone_device_time ='2011-06-06 05:24:42',last_checkin ='2011-06-06 05:35:07'

交易2

iphone_device_time ='2011-06-06 05:35:09',last_checkin ='2011-06-06 05:24:42'

请注意,列值已翻转。通常,当两个不同的事务正在从两个表访问两个锁时发生死锁,其中TX1(事务1)获取行A,然后行B,而TX2获取行B,然后行A。在这种情况下,TX1和TX2是访问同一行,但更改两个不同的列(iphone_device_time,last_checkin)。

这些值没有任何意义。在5:24:42,您最后一次签到时间是5:35:07。十分钟零二十七秒后(5:35:07-05:24:42),列值将反转。

最大的问题是:为什么TX1保持了将近11分钟?

这不是真正的答案。这只是带宽,对我而言始终如此。我希望这些观察对您有所帮助。

更新2011-06-06 09:57

请检查有关innodb_locks_unsafe_for_binlog的链接:我建议阅读此文件的原因是您在INNODB STATUS屏幕中看到的其他内容。短语lock_mode X(排他锁)和lock_mode S(共享锁)表示将两个锁强加(或试图强加)在同一行上。在进行下一行锁定时,可能会进行一些内部序列化。默认为关闭。阅读此内容后,您可能需要考虑启用它。

更新2011-06-06 10:03

检查此思路的另一个原因是所有事务都遍历了PRIMARY键。由于PRIMARY是InnoDB中的聚簇索引,因此PRIMARY键和行本身在一起。因此,遍历行和PRIMARY KEY是相同的。因此,PRIMARY KEY上的任何索引锁也都是行级锁。

更新2011-06-06 19:21

检查您拥有什么auocommit。如果关闭了自动提交,我会看到两(2)个可能的问题

  1. 在同一事务中两次更新同一行
  2. 在两个不同的事务中更新同一行

实际上,您在问题中显示的SHOW ENGINE INNODB STATUS确实具有这两种情况。


感谢您的输入。我们也注意到了这一点。我很困惑为什么对同一行的两列进行更改会导致死锁。
RedBlueThing 2011年

感谢您的更新。我只是检查了设置并打开了自动提交功能(即我们没有更改默认设置)。
RedBlueThing 2011年

@RedBlueThing请去看看你的事务隔离级别(变量TX_ISOLATION dev.mysql.com/doc/refman/5.5/en/...)。如果未设置,则默认值为REPEATABLE-READ。不同的事务隔离级别可能会有助于解决这种独特情况。
RolandoMySQLDBA 2011年

谢谢。我会检查一下,然后回覆您。再次感谢您的坚持:)
RedBlueThing 2011年

我今天早上在日志中发现了一个不同的僵局,这可能可以弄清楚这个问题。我将其发布为一个单独的问题,以使事情保持简单。dba.stackexchange.com/questions/3223/…– RedBlueThing 2011
6

1

Rolando的回答无疑有助于我们找到正确的解决方案。但是,我们最终并没有调整自动提交配置,隔离级别或innodb_locks_unsafe_for_binlog配置。

我们认为我们在第一个问题上发布的死锁日志是我们随后发现并在此处发布的死锁的结果。由于我们通过这两个查询解决了该问题,因此此后再也没有出现任何僵局。


尽管我找不到解决方案,但我很高兴可以提供帮助!
RolandoMySQLDBA 2011年

感谢您考虑我的建议和MySQL随机发(+1)!!!
RolandoMySQLDBA 2011年

@RolandoMySQLDBA没问题;)感谢您的帮助。
RedBlueThing 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.