Réponses:
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 Locked
et 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.
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 PROCESSLIST
est que vous ne verrez pas les verrous à moins que d'autres requêtes ne soient mises en file d'attente.
Essayez SHOW OPEN TABLES
:
show open tables where In_Use > 0 ;
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_LOCKS
est 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_LOCKS
est obsolète de toute façon.
SHOW ENGINE INNODB STATUS
est inutile: someTable
n'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_history
et performance_schema.threads
pour 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 someTable
est 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.
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