Odpowiedzi:
Zobacz link Marko do tabel InnoDB i ostrzeżeń.
Dla MyISAM nie jest to łatwe rozwiązanie „to obraźliwe zapytanie”. Zawsze powinieneś zacząć od listy procesów. Pamiętaj jednak, aby dołączyć pełne słowo kluczowe, aby drukowane zapytania nie były obcinane:
SHOW FULL PROCESSLIST;
Spowoduje to wyświetlenie listy wszystkich bieżących procesów, ich zapytań SQL i stanu. Zwykle teraz, gdy jedno zapytanie powoduje zablokowanie wielu innych, identyfikacja powinna być łatwa. Kwerendy, których dotyczy problem, będą miały status, Locked
a niepoprawne zapytanie będzie siedziało samo, prawdopodobnie czekając na coś intensywnego, na przykład tymczasową tabelę.
Jeśli nie jest to oczywiste, będziesz musiał użyć swoich uprawnień do dedukcji SQL, aby ustalić, który fragment obrażającego SQL może być przyczyną twoich nieszczęść.
Jeśli korzystasz z InnoDB i chcesz sprawdzić uruchomione zapytania, polecam
show engine innodb status;
jak wspomniano w łączu Marko. To da ci zapytanie blokujące, ile wierszy / tabel jest przez niego zablokowanych itp. Zajrzyj do TRANSAKCJI.
Problem z używaniem SHOW PROCESSLIST
polega na tym, że blokady nie będą widoczne, dopóki inne zapytania nie ustawią się w kolejce.
Spróbuj SHOW OPEN TABLES
:
show open tables where In_Use > 0 ;
Żadna z odpowiedzi nie pokazuje wszystkich blokad, które są aktualnie wstrzymywane.
Zrób to np. W mysql w terminalu.
start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there
Oczywiście powyższa transakcja zawiera blokadę, ponieważ transakcja jest nadal aktywna. Ale w tej chwili nie odbywa się żadne zapytanie i nikt nie czeka nigdzie na zamek (przynajmniej jeszcze).
INFORMATION_SCHEMA.INNODB_LOCKS
jest pusta, co ma sens, biorąc pod uwagę dokumentację , ponieważ jest tylko jedna transakcja i obecnie nikt nie czeka na żadne blokady. I INNODB_LOCKS
tak jest przestarzałe.
SHOW ENGINE INNODB STATUS
jest bezużyteczny: someTable
w ogóle nie jest wspomniany
SHOW FULL PROCESSLIST
jest pusty, ponieważ sprawca aktualnie nie uruchamia zapytania.
Można użyć INFORMATION_SCHEMA.INNODB_TRX
, performance_schema.events_statements_history
i performance_schema.threads
wyodrębnić zapytań wszelkie aktywne transakcje wykonywane w przeszłości, jak przedstawiono w drugiej moją odpowiedź , ale nie natknąć żaden sposób, aby zobaczyć, że someTable
jest zablokowana w powyższym scenariuszu.
Sugestie zawarte w innych odpowiedziach do tej pory przynajmniej nie pomogą.
Oświadczenie: Nie mam zainstalowanego programu Innotop i nie zawracałem sobie głowy. Może to może zadziałać.
Referencje zaczerpnięte z tego postu.
Możesz użyć poniższego skryptu:
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