Difficulté à déchiffrer un blocage dans un journal d'état innodb


16

Nous accédons à MySQL à partir du connecteur Microsoft ADO.NET.

Parfois, nous voyons l'impasse suivante dans notre statut innodb et nous n'avons pas pu identifier la cause du problème. Il semble que la transaction (2) attend et garde le même verrou?

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

Nous avons lu cet article sur le prochain verrouillage des touches, mais il ne semble pas s'appliquer à nous car nous ne faisons pas de sélections pour la mise à jour.

Mise à jour

Ce matin, j'ai découvert une signature d'impasse légèrement différente qui pourrait être la cause première de cette impasse. J'ai publié cette impasse comme une question distincte pour garder les choses simples. Je mettrai à jour ici si je peux confirmer que l'autre question est la cause.


J'ai mis à jour ma réponse avec plus de bande passante et de débit.
RolandoMySQLDBA

J'ai mis à jour ma réponse avec quelque chose sur l'autocommit
RolandoMySQLDBA

BTW Vous obtenez un +1 pour cette question car ce type de question devrait garder les DBA sur leurs gardes.
RolandoMySQLDBA

Réponses:


6

Voici ce que je vois

Je vois trois requêtes, toutes presque identiques.

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;

Les différences

TRANSACTION 1

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

TRANSACTION 2

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

Veuillez noter que les valeurs des colonnes sont inversées. Normalement, un blocage se produit lorsque deux transactions différentes accèdent à deux verrous à partir de deux tables avec TX1 (transaction 1) obtenant la ligne A puis la ligne B tandis que TX2 obtient la ligne B puis la ligne A. Dans ce cas, c'est TX1 et TX2 sont accéder à la même ligne mais changer deux colonnes différentes (iphone_device_time, last_checkin).

Les valeurs n'ont aucun sens. À 5:24:42, votre dernier enregistrement était 5:35:07. Dix minutes et 27 secondes plus tard (5:35:07 - 05:24:42), les valeurs des colonnes sont inversées.

La grande question est: pourquoi TX1 est-il retenu pendant près de 11 minutes ???

Ce n'est pas vraiment une réponse. C'est juste de la bande passante et tout au long de moi. J'espère que ces observations vous aideront.

MISE À JOUR 2011-06-06 09:57

Veuillez consulter ce lien concernant innodb_locks_unsafe_for_binlog : la raison pour laquelle je suggère de lire ceci est autre chose que j'ai vu dans votre écran INNODB STATUS. L'expression lock_mode X (verrou exclusif) et lock_mode S (verrou partagé) indique que les deux verrous sont imposés (ou tentent de s'imposer) sur la même ligne. Il peut y avoir une sérialisation interne en cours lors du verrouillage de la ligne suivante. La valeur par défaut est OFF. Après avoir lu ceci, vous devrez peut-être envisager de l'activer.

MISE À JOUR 2011-06-06 10:03

Une autre raison d'examiner cette ligne de pensée est le fait que toutes les transactions traversent la clé PRIMARY. Étant donné que PRIMARY est un index cluster dans InnoDB, la clé PRIMARY et la ligne elle-même sont ensemble. Ainsi, parcourir une ligne et et la CLÉ PRIMAIRE sont une seule et même chose. Par conséquent, tout verrou d'index sur la CLÉ PRIMAIRE est également un verrou de niveau ligne.

MISE À JOUR 2011-06-06 19:21

Vérifiez quelle valeur auocommit vous avez . Si la validation automatique est désactivée, je peux voir deux (2) problèmes possibles

  1. mettre à jour deux fois la même ligne dans la même transaction
  2. mise à jour de la même ligne dans deux transactions différentes

En fait, le SHOW ENGINE INNODB STATUS que vous montrez dans la question a exactement les deux scénarios.


Merci pour votre contribution. Nous l'avons également remarqué. Je ne comprends pas pourquoi les modifications apportées à deux colonnes sur la même ligne entraîneraient un blocage.
RedBlueThing

Merci pour vos mises à jour. Je viens de vérifier nos paramètres et la validation automatique est activée (c'est-à-dire que nous n'avons pas changé la valeur par défaut).
RedBlueThing

@RedBlueThing Veuillez vérifier le niveau d'isolement de votre transaction (la variable est tx_isolation dev.mysql.com/doc/refman/5.5/en/… ). Si vous ne le définissez pas, la valeur par défaut est REPEATABLE-READ. il est possible qu'un niveau d'isolement de transaction différent puisse aider dans cette situation unique.
RolandoMySQLDBA

Merci. Je vérifierai cela et je vous répondrai. Merci encore pour votre persévérance :)
RedBlueThing

J'ai découvert une impasse différente dans nos journaux ce matin qui pourrait éclairer ce problème. J'ai posté cela comme une question distincte pour garder les choses simples. dba.stackexchange.com/questions/3223/…
RedBlueThing

1

La réponse de Rolando a certainement été utile pour nous aider à trouver la bonne solution. Cependant, nous n'avons finalement pas ajusté notre configuration d' autocommit , nos niveaux d'isolement ou la configuration innodb_locks_unsafe_for_binlog .

Nous pensons que le journal des blocages que nous avons publié sur cette première question est le résultat du blocage que nous avons ensuite trouvé et publié ici . Depuis que nous avons résolu le problème avec ces deux requêtes, nous n'avons vu aucun blocage depuis.


Bien que je n'aie pas trouvé la solution, j'étais heureux d'avoir pu aider !!!
RolandoMySQLDBA

Merci d'avoir pris en compte mes suggestions et les babillages MySQL aléatoires (+1) !!!
RolandoMySQLDBA

@RolandoMySQLDBA Pas de problème;) Merci pour l'aide.
RedBlueThing
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.