Comment puis-je afficher les verrous mysql?

45

Est-il possible d'afficher tous les verrous actifs dans une base de données mysql?

Rory
la source
1
Vous pouvez interroger les tables INNODB_LOCK_WAITS et INNODB_LOCKS.

Réponses:

40

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

Pour MyISAM, il n’existe 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 provoque le verrouillage de nombreuses autres, elle devrait être facile à identifier. Les requêtes affectées auront un statut Lockedet la requête incriminée restera en suspens, attendant éventuellement 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 de code SQL incriminé peut être à l'origine de vos problèmes.

Dan Carley
la source
21

Si vous utilisez InnoDB et que vous avez besoin de vérifier les requêtes en cours, je vous le 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 par celle-ci, etc. Consultez la rubrique TRANSACTIONS.

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

Polymorphix
la source
20

Essayez SHOW OPEN TABLES:

show open tables where In_Use > 0 ;
M Sleman
la source
Je pense que c'est le meilleur moyen d'identifier immédiatement les verrous en cours d'utilisation, surtout si vous avez plusieurs bases de données et des centaines de connexions.
Nelaaro
7

Utiliser cette commande

SHOW PROCESSLIST

montrera tous les processus en cours d'exécution, y compris les processus ayant acquis le verrouillage sur les tables.

Arie K
la source
7

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

Faites ceci par exemple 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

Il est clair que la transaction ci-dessus est verrouillée, car la transaction est toujours active. Mais aucune requête n'est en cours pour le moment et personne n'attend un verrou nulle part (encore au moins).

INFORMATION_SCHEMA.INNODB_LOCKSest vide, ce qui est logique compte tenu de la documentation , car il n'y a qu'une seule transaction et, pour le moment, personne n'attend de verrou. Aussi INNODB_LOCKSest obsolète de toute façon.

SHOW ENGINE INNODB STATUSest inutile: someTablen'est pas mentionné du tout

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

Vous pouvez utiliser INFORMATION_SCHEMA.INNODB_TRX, performance_schema.events_statements_historyet performance_schema.threadspour extraire les requêtes que toutes les transactions actives ont exécuté dans le passé comme indiqué dans mon autre réponse , mais je n'ai pas rencontré une façon de voir qui someTableest verrouillé dans le scénario ci - dessus.

Les suggestions dans les autres réponses jusqu’à présent n’aideront pas du moins.

Avertissement: je n'ai pas innotop installé et je ne me suis pas ennuyé. Peut-être que cela pourrait fonctionner.

Peter V. Mørch
la source
6

Autant que je sache, il n’ya toujours pas de méthode native dans MYSQL, mais j’utilise innotop . C'est gratuit et comporte de nombreuses autres fonctionnalités.

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

Marko Carter
la source
4

Référence prise 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
Anvesh
la source