Probleme beim Entschlüsseln eines Deadlocks in einem Innodb-Statusprotokoll


16

Wir greifen über den Microsoft ADO.NET Connector auf MySQL zu.

Gelegentlich sehen wir den folgenden Deadlock in unserem Innodb-Status und konnten die Ursache des Problems nicht identifizieren. Es sieht so aus, als ob Transaktion (2) auf dieselbe Sperre wartet und diese hält.

------------------------
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)

Wir haben diesen Artikel zur nächsten Tastensperre gelesen , aber er scheint nicht auf uns zuzutreffen, da wir keine Auswahl für die Aktualisierung treffen.

Aktualisieren

Heute Morgen habe ich eine etwas andere Deadlock-Signatur entdeckt, die die Ursache für diesen Deadlock sein könnte. Ich habe diesen Deadlock als separate Frage veröffentlicht , um die Dinge einfach zu halten. Ich werde hier aktualisieren, wenn ich bestätigen kann, dass die andere Frage die Ursache ist.


Ich habe meine Antwort mit mehr Bandbreite und Durchsatz aktualisiert.
RolandoMySQLDBA

Ich habe meine Antwort mit etwas über
Autocommit

Übrigens, Sie erhalten +1 für diese Frage, da diese Art von Frage die Datenbankadministratoren auf Trab halten sollte.
RolandoMySQLDBA

Antworten:


6

Hier ist was ich sehe

Ich sehe drei Fragen, die fast identisch sind.

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;

Die Unterschiede

TRANSAKTION 1

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

TRANSAKTION 2

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

Bitte beachten Sie, dass die Spaltenwerte gespiegelt sind. Normalerweise tritt ein Deadlock auf, wenn zwei verschiedene Transaktionen auf zwei Sperren von zwei Tabellen zugreifen, wobei TX1 (Transaktion 1) Zeile A und dann Zeile B erhält, während TX2 Zeile B und dann Zeile A erhält. In diesem Fall ist dies TX1 und TX2 Zugreifen auf dieselbe Zeile, aber Ändern von zwei verschiedenen Spalten (iphone_device_time, last_checkin).

Die Werte ergeben keinen Sinn. Um 5:24:42 Uhr haben Sie zuletzt um 5:35:07 Uhr eingecheckt. Zehn Minuten und 27 Sekunden später (5:35:07 - 05:24:42) werden die Spaltenwerte umgekehrt.

Die große Frage ist: Warum wird TX1 fast 11 Minuten lang gehalten ???

Dies ist keine wirkliche Antwort. Das ist nur Bandbreite und überall von mir. Ich hoffe, diese Beobachtungen helfen.

UPDATE 2011-06-06 09:57

Bitte überprüfen Sie diesen Link bezüglich innodb_locks_unsafe_for_binlog : Der Grund, warum ich dies vorschlage, ist etwas anderes, das ich in Ihrer INNODB STATUS-Anzeige gesehen habe. Der Ausdruck lock_mode X (exklusive Sperre) und lock_mode S (gemeinsame Sperre) gibt an, dass beide Sperren für dieselbe Zeile gelten (oder versucht werden, sie durchzusetzen). Möglicherweise wird die nächste Zeile durch interne Serialisierung gesperrt. Die Standardeinstellung ist AUS. Nachdem Sie dies gelesen haben, müssen Sie möglicherweise in Betracht ziehen, es zu aktivieren.

UPDATE 2011-06-06 10:03

Ein weiterer Grund, diesen Gedankengang zu untersuchen, ist die Tatsache, dass alle Transaktionen den PRIMARY-Schlüssel durchlaufen. Da der PRIMARY ein Clustered-Index in InnoDB ist, sind der PRIMARY-Schlüssel und die Zeile selbst zusammen. Durchqueren einer Reihe und und der PRIMARY KEY sind also ein und dasselbe. Daher ist jede Indexsperre für den PRIMARY KEY auch eine Sperre auf Zeilenebene.

UPDATE 2011-06-06 19:21

Überprüfen Sie, welchen Auocommit- Wert Sie haben . Wenn die automatische Festschreibung deaktiviert ist, werden zwei (2) mögliche Probleme angezeigt

  1. zweimaliges Aktualisieren derselben Zeile in derselben Transaktion
  2. Aktualisieren derselben Zeile in zwei verschiedenen Transaktionen

Der SHOW ENGINE INNODB STATUS, den Sie in der Frage anzeigen, enthält genau beide Szenarien.


Danke für deinen Beitrag. Das ist uns auch aufgefallen. Ich bin verwirrt, warum Änderungen an zwei Spalten in derselben Zeile zu einem Deadlock führen würden.
RedBlueThing

Danke für eure Updates. Ich habe gerade unsere Einstellungen überprüft und Autocommit ist aktiviert (dh wir haben die Standardeinstellung nicht geändert).
RedBlueThing

@RedBlueThing Sehen Sie sich die Isolationsstufe Ihrer Transaktion an (Variable ist tx_isolation dev.mysql.com/doc/refman/5.5/en/… ). Wenn Sie dies nicht festlegen, lautet die Standardeinstellung REPEATABLE-READ. Möglicherweise hilft eine andere Transaktionsisolationsstufe in dieser einzigartigen Situation.
RolandoMySQLDBA

Vielen Dank. Ich werde das überprüfen und mich bei Ihnen melden.
Nochmals vielen

Ich habe heute Morgen einen anderen Deadlock in unseren Protokollen entdeckt, der möglicherweise etwas Licht in dieses Problem bringt. Ich habe das als separate Frage gepostet, um die Dinge einfach zu halten. dba.stackexchange.com/questions/3223/…
RedBlueThing

1

Rolandos Antwort war sicherlich hilfreich, um uns auf den Weg zur richtigen Lösung zu bringen. Letztendlich haben wir jedoch weder unsere Autocommit- Konfiguration noch unsere Isolationsstufen oder die innodb_locks_unsafe_for_binlog- Konfiguration angepasst .

Wir glauben, dass das Deadlock-Protokoll, das wir in dieser ersten Frage gepostet haben, ein Ergebnis des Deadlocks ist, den wir später gefunden und hier gepostet haben . Seit wir das Problem mit diesen beiden Abfragen behoben haben, sind keine Deadlocks mehr aufgetreten.


Obwohl ich die Lösung nicht finden konnte, war ich froh, dass ich helfen konnte !!!
RolandoMySQLDBA

Vielen Dank für die Berücksichtigung meiner Vorschläge und zufälligen MySQL-Babblings (+1) !!!
RolandoMySQLDBA

@RolandoMySQLDBA Kein Problem;) Danke für die Hilfe.
RedBlueThing
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.