Risposte:
Vedi il link di Marko per le tabelle InnoDB e le avvertenze.
Per MyISAM, non esiste una soluzione estremamente semplice "questa è la query offensiva". Dovresti sempre iniziare con un elenco di processi. Assicurati di includere la parola chiave completa in modo che le query stampate non vengano troncate:
SHOW FULL PROCESSLIST;
Questo ti mostrerà un elenco di tutti i processi correnti, la loro query SQL e lo stato. Ora di solito se una singola query sta causando il blocco di molti altri, dovrebbe essere facile da identificare. Le query interessate avranno uno stato di Locked
e la query offensiva rimarrà da sola, probabilmente in attesa di qualcosa di intenso, come una tabella temporanea.
Se non è ovvio, dovrai usare i tuoi poteri di deduzione SQL per determinare quale parte di SQL offensiva potrebbe essere la causa dei tuoi guai.
Se usi InnoDB e devi controllare le query in esecuzione, ti consiglio
show engine innodb status;
come menzionato nel link di Marko. Questo ti darà la query di blocco, quante righe / tabelle sono bloccate da esso ecc. Guarda in TRANSAZIONI.
Il problema con l'utilizzo SHOW PROCESSLIST
è che non vedrai i blocchi a meno che altre query non siano in coda.
Prova SHOW OPEN TABLES
:
show open tables where In_Use > 0 ;
Nessuna delle risposte può mostrare tutti i blocchi attualmente presenti.
Fallo ad esempio in mysql in un terminale.
start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there
Chiaramente la transazione sopra contiene un blocco, perché la transazione è ancora attiva. Ma nessuna query è in corso in questo momento e nessuno è in attesa di un blocco ovunque (almeno almeno).
INFORMATION_SCHEMA.INNODB_LOCKS
è vuoto, il che ha senso data la documentazione , perché esiste una sola transazione e attualmente nessuno è in attesa di blocchi. Inoltre INNODB_LOCKS
è deprecato comunque.
SHOW ENGINE INNODB STATUS
è inutile: someTable
non è menzionato affatto
SHOW FULL PROCESSLIST
è vuoto perché il colpevole non sta eseguendo una query in questo momento.
È possibile utilizzare INFORMATION_SCHEMA.INNODB_TRX
, performance_schema.events_statements_history
e performance_schema.threads
per estrarre le query che tutte le transazioni attive hanno eseguito in passato come delineato nella mia altra risposta , ma non mi sono imbattuto in un modo di vedere che someTable
è bloccato nello scenario precedente.
I suggerimenti nelle altre risposte finora non aiuteranno almeno.
Disclaimer: non ho installato innotop e non mi sono preoccupato. Forse potrebbe funzionare.
AFAIK non c'è ancora modo nativo in MYSQL, ma io uso innotop . È gratuito e ha anche molte altre funzionalità.
Vedi anche questo link per maggiori informazioni sull'uso dello strumento innotop.
Riferimento tratto da questo post.
Puoi usare lo script seguente:
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