Respuestas:
Vea el enlace de Marko para las tablas de InnoDB y las advertencias.
Para MyISAM, no hay una solución fácil de "esta es la consulta ofensiva". Siempre debe comenzar con una lista de procesos. Pero asegúrese de incluir la palabra clave completa para que las consultas impresas no se trunqueen:
SHOW FULL PROCESSLIST;
Esto le mostrará una lista de todos los procesos actuales, su consulta SQL y su estado. Ahora, por lo general, si una sola consulta está causando el bloqueo de muchas otras, debería ser fácil de identificar. Las consultas afectadas tendrán un estado Locked
y la consulta infractora se quedará sola, posiblemente esperando algo intensivo, como una tabla temporal.
Si no es obvio, tendrá que usar sus poderes de deducción de SQL para determinar qué parte de SQL ofensivo puede ser la causa de sus problemas.
Si usa InnoDB y necesita verificar las consultas en ejecución, le recomiendo
show engine innodb status;
como se menciona en el enlace de Marko. Esto le dará la consulta de bloqueo, cuántas filas / tablas está bloqueada por ella, etc. Busque en TRANSACCIONES.
El problema con el uso SHOW PROCESSLIST
es que no verá los bloqueos a menos que otras consultas estén en cola.
Prueba SHOW OPEN TABLES
:
show open tables where In_Use > 0 ;
Ninguna de las respuestas puede mostrar todos los bloqueos que se encuentran actualmente.
Haga esto, por ejemplo, en mysql en una terminal.
start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there
Claramente, la transacción anterior tiene un bloqueo, porque la transacción aún está activa. Pero en este momento no se está realizando ninguna consulta y nadie está esperando un bloqueo en ningún lugar (al menos al menos).
INFORMATION_SCHEMA.INNODB_LOCKS
está vacío, lo que tiene sentido dada la documentación , porque solo hay una transacción y actualmente nadie espera ningún bloqueo. También INNODB_LOCKS
está en desuso de todos modos.
SHOW ENGINE INNODB STATUS
es inútil: someTable
no se menciona en absoluto
SHOW FULL PROCESSLIST
está vacío, porque el culpable no está ejecutando una consulta en este momento.
Se puede utilizar INFORMATION_SCHEMA.INNODB_TRX
, performance_schema.events_statements_history
y performance_schema.threads
para extraer las consultas que cualquier transacción activa han ejecutado en el pasado como se indica en mi otra respuesta , pero no he encontrado ninguna manera de ver que someTable
está encerrado en el escenario anterior.
Las sugerencias en las otras respuestas hasta ahora no ayudarán al menos.
Descargo de responsabilidad: no tengo instalado innotop y no me molesté. Quizás eso podría funcionar.
AFAIK todavía no hay una forma nativa en MYSQL, pero uso innotop . Es gratis y tiene muchas otras funciones también.
Consulte también este enlace para obtener más información sobre el uso de la herramienta innotop.
Referencia tomada de esta publicación.
Puede usar el siguiente script:
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