Come posso mostrare i blocchi mysql?


45

Esiste un modo per mostrare tutti i blocchi attivi in ​​un database mysql?


1
È possibile eseguire query sulle tabelle INNODB_LOCK_WAITS e INNODB_LOCKS.

Risposte:


40

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 Lockede 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.


21

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.


20

Prova SHOW OPEN TABLES:

show open tables where In_Use > 0 ;

Penso che questo sia il modo migliore per identificare immediatamente i blocchi in uso, specialmente se si dispone di più database e centinaia di connessioni.
nelaaro,

7

Usando questo comando

SHOW PROCESSLIST

mostrerà tutto il processo attualmente in esecuzione, incluso il processo che ha acquisito il blocco sulle tabelle.


7

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: someTablenon è 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_historye performance_schema.threadsper 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.


6

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.


4

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.