web-dev-qa-db-fra.com

Comment afficher les verrous mysql?

Existe-t-il de toute façon d'afficher tous les verrous actifs dans une base de données mysql?

54
Rory

Voir le lien de Marko pour les tables InnoDB et les mises en garde.

Pour MyISAM, il n'y a pas de solution simple et facile "c'est la requête incriminée". Vous devriez toujours commencer par une liste de processus. Mais assurez-vous d'inclure le mot clé complet afin que les requêtes imprimées ne soient pas tronquées:

SHOW FULL PROCESSLIST;

Cela vous montrera une liste de tous les processus en cours, leur requête SQL et leur état. Maintenant, généralement, si une seule requête entraîne le verrouillage de nombreuses autres, elle devrait être facile à identifier. Les requêtes affectées auront le statut Locked et la requête incriminée sera suspendue d'elle-même, attendant peut-être quelque chose d'intensif, comme une table temporaire.

Si ce n'est pas évident, vous devrez utiliser vos pouvoirs de déduction SQL pour déterminer quel élément SQL offensant peut être la cause de vos problèmes.

47
Dan Carley

Si vous utilisez InnoDB et avez besoin de vérifier les requêtes en cours, je recommande

show engine innodb status;

comme mentionné dans le lien de Marko. Cela vous donnera la requête de verrouillage, combien de lignes/tables sont verrouillées, etc. Regardez sous TRANSACTIONS.

Le problème avec l'utilisation de SHOW PROCESSLIST signifie que vous ne verrez pas les verrous à moins que d'autres requêtes ne soient en attente.

26
Polymorphix

Essayez SHOW OPEN TABLES :

show open tables where In_Use > 0 ;
24
M Sleman

Aucune des réponses ne peut afficher tous les verrous actuellement détenus.

Faites ceci par ex. dans mysql dans un terminal.

start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there

De toute évidence, la transaction ci-dessus détient un verrou, car la transaction est toujours active. Mais aucune requête n'est en cours en ce moment et personne n'attend un verrou nulle part (au moins).

INFORMATION_SCHEMA.INNODB_LOCKS est vide, ce qui est logique étant donné la documentation , car il n'y a qu'une seule transaction et actuellement personne n'attend de verrous. Aussi INNODB_LOCKS est de toute façon obsolète.

SHOW ENGINE INNODB STATUS est inutile: someTable n'est pas du tout mentionné

SHOW FULL PROCESSLIST est vide, car le coupable n'exécute pas de requête pour le moment.

Vous pouvez utiliser INFORMATION_SCHEMA.INNODB_TRX, performance_schema.events_statements_history et performance_schema.threads pour extraire les requêtes que toutes les transactions actives ont exécutées dans le passé comme indiqué dans mon autre réponse , mais je n'ai trouvé aucun moyen de voir que someTable est verrouillé le scénario ci-dessus.

Jusqu'à présent, les suggestions des autres réponses ne seront d'aucune utilité.

Avertissement: je n'ai pas installé innotop et je n'ai pas pris la peine. Peut-être que pourrait fonctionner.

11
Peter V. Mørch

Utilisation de cette commande

SHOW PROCESSLIST

affichera tous les processus en cours d'exécution, y compris les processus qui ont acquis un verrou sur les tables.

7
Arie K

AFAIK il n'y a toujours pas de méthode native dans MYSQL, mais j'utilise innotop . Il est gratuit et propose également de nombreuses autres fonctionnalités.

Voir aussi ce lien pour plus d'informations sur l'utilisation de l'outil innotop.

7
Marko Carter

Référence tirée de ce post.

Vous pouvez utiliser le script ci-dessous:

SELECT 
    pl.id
    ,pl.user
    ,pl.state
    ,it.trx_id 
    ,it.trx_mysql_thread_id 
    ,it.trx_query AS query
    ,it.trx_id AS blocking_trx_id
    ,it.trx_mysql_thread_id AS blocking_thread
    ,it.trx_query AS blocking_query
FROM information_schema.processlist AS pl 
INNER JOIN information_schema.innodb_trx AS it
    ON pl.id = it.trx_mysql_thread_id
INNER JOIN information_schema.innodb_lock_waits AS ilw
    ON it.trx_id = ilw.requesting_trx_id 
        AND it.trx_id = ilw.blocking_trx_id
5
Anvesh