Problemi nella decodifica di un deadlock in un registro di stato innodb


16

Stiamo accedendo a MySQL dal connettore Microsoft ADO.NET.

Occasionalmente stiamo vedendo il seguente deadlock nel nostro stato innodb e non siamo stati in grado di identificare la causa del problema. Sembra che la transazione (2) stia aspettando e mantenendo lo stesso lucchetto?

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

Leggiamo questo articolo sul prossimo blocco dei tasti, ma non sembra applicabile a noi perché non stiamo effettuando selezioni per l'aggiornamento.

Aggiornare

Questa mattina ho scoperto una firma di deadlock leggermente diversa che potrebbe essere la causa principale di questo deadlock. Ho pubblicato quel deadlock come una domanda separata per semplificare le cose. Aggiornerò qui se posso confermare che l'altra domanda è la causa.


Ho aggiornato la mia risposta con maggiore larghezza di banda e velocità effettiva.
RolandoMySQLDBA,

Ho aggiornato la mia risposta con qualcosa su autocommit
RolandoMySQLDBA,

A proposito, ottieni un +1 per questa domanda perché questo tipo di domanda dovrebbe tenere i DBA in punta di piedi.
RolandoMySQLDBA

Risposte:


6

Ecco cosa sto vedendo

Vedo tre domande, tutte quasi identiche.

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;

Le differenze

TRANSAZIONE 1

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

TRANSAZIONE 2

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

Si noti che i valori della colonna sono invertiti. Normalmente, un deadlock si verifica quando due diverse transazioni accedono a due blocchi da due tabelle con TX1 (Transazione 1) che ottiene la riga A e quindi la riga B mentre TX2 sta ottenendo la riga B e quindi la riga A. In questo caso, è TX1 e TX2 sono accedendo alla stessa riga ma modificando due colonne diverse (iphone_device_time, last_checkin).

I valori non hanno alcun senso. Alle 5:24:42, il tuo ultimo check-in è stato alle 5:35:07. Dieci minuti e 27 secondi dopo (5:35:07 - 05:24:42), i valori della colonna vengono invertiti.

La grande domanda è: perché TX1 viene trattenuto per quasi 11 minuti ???

Questa non è davvero una risposta. Questa è solo la larghezza di banda e da parte mia. Spero che queste osservazioni aiutino.

AGGIORNAMENTO 2011-06-06 09:57

Dai un'occhiata a questo link relativo a innodb_locks_unsafe_for_binlog : il motivo per cui ti suggerisco di leggere questo è qualcos'altro che ho visto sul tuo display INNODB STATUS. La frase lock_mode X (blocco esclusivo) e lock_mode S (blocco condiviso) indica che entrambi i blocchi sono stati imposti (o tentano di imporre) sulla stessa riga. Potrebbe esserci della serializzazione interna in corso durante il blocco della riga successiva. L'impostazione predefinita è OFF. Dopo aver letto questo, potresti dover considerare di abilitarlo.

AGGIORNAMENTO 2011-06-06 10:03

Un altro motivo per esaminare questa linea di pensiero è il fatto che tutte le transazioni attraversano la chiave PRIMARY. Poiché PRIMARY è un indice cluster in InnoDB, la chiave PRIMARY e la riga stessa sono insieme. Quindi, attraversare una riga e il PRIMARY KEY sono la stessa cosa. Pertanto, qualsiasi blocco dell'indice sul PRIMARY KEY è anche un blocco a livello di riga.

AGGIORNAMENTO 2011-06-06 19:21

Controlla quale valore di auocommit hai . Se autocommit è disattivato, vedo due (2) possibili problemi

  1. aggiornando la stessa riga due volte nella stessa transazione
  2. aggiornando la stessa riga in due diverse transazioni

In effetti, lo SHOW ENGINE INNODB STATUS che mostri nella domanda ha esattamente entrambi gli scenari.


Grazie per il tuo contributo. Lo abbiamo notato anche noi. Sono confuso perché le modifiche a due colonne sulla stessa riga comporterebbero un deadlock.
RedBlueThing

Grazie per i tuoi aggiornamenti Ho appena controllato le nostre impostazioni e autocommit è attivato (ovvero non abbiamo modificato l'impostazione predefinita).
RedBlueThing

@RedBlueThing Esamina il livello di isolamento della tua transazione (la variabile è tx_isolation dev.mysql.com/doc/refman/5.5/en/… ). Se non lo imposti, il valore predefinito è REPEATABLE-READ. è possibile che un diverso livello di isolamento delle transazioni possa aiutare in questa situazione unica.
RolandoMySQLDBA

Grazie. Lo controllerò e ti ricontatterò. Grazie ancora per la tua persistenza :)
RedBlueThing

Stamattina ho scoperto un diverso deadlock nei nostri registri che potrebbe far luce su questo problema. L'ho pubblicato come domanda separata per semplificare le cose. dba.stackexchange.com/questions/3223/…
RedBlueThing

1

La risposta di Rolando è stata sicuramente utile nel portarci sulla strada per la giusta soluzione. Tuttavia, alla fine non abbiamo modificato la nostra configurazione di autocommit , i nostri livelli di isolamento o la configurazione innodb_locks_unsafe_for_binlog .

Riteniamo che il registro dei deadlock che abbiamo pubblicato su questa prima domanda sia il risultato del deadlock che abbiamo successivamente trovato e pubblicato qui . Da quando abbiamo risolto il problema con queste due query, da allora non abbiamo riscontrato alcun deadlock.


Anche se non sono riuscito a trovare la soluzione, sono stato felice di poterti aiutare !!!
RolandoMySQLDBA,

Grazie per aver considerato i miei suggerimenti e i babbling casuali di MySQL (+1) !!!
RolandoMySQLDBA,

@RolandoMySQLDBA Nessun problema;) Grazie per l'aiuto.
RedBlueThing
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.