Wie kann ich MySQL-Sperren anzeigen?

44

Gibt es überhaupt alle Sperren anzuzeigen, die in einer MySQL-Datenbank aktiv sind?

Rory
quelle
1
Sie können die Tabellen INNODB_LOCK_WAITS und INNODB_LOCKS abfragen.

Antworten:

39

Siehe Markos Link für InnoDB-Tabellen und die Vorbehalte.

Für MyISAM gibt es keine besonders einfache Lösung für "Dies ist die problematische Abfrage". Sie sollten immer mit einer Prozessliste beginnen. Stellen Sie jedoch sicher, dass Sie das vollständige Schlüsselwort angeben, damit die gedruckten Abfragen nicht abgeschnitten werden:

SHOW FULL PROCESSLIST;

Dies zeigt Ihnen eine Liste aller aktuellen Prozesse, deren SQL-Abfrage und Status. Wenn eine einzelne Abfrage dazu führt, dass viele andere gesperrt werden, sollte dies normalerweise leicht zu erkennen sein. Die betroffenen Abfragen haben den Status Lockedund die anstößige Abfrage wartet möglicherweise auf etwas Intensives wie eine temporäre Tabelle.

Wenn dies nicht offensichtlich ist, müssen Sie Ihre SQL-Abzugskraft einsetzen, um zu bestimmen, welches SQL-Problem die Ursache Ihrer Probleme sein kann.

Dan Carley
quelle
20

Wenn Sie InnoDB verwenden und laufende Abfragen überprüfen müssen, empfehle ich

show engine innodb status;

wie in Markos Link erwähnt. Dadurch erhalten Sie die Sperrabfrage, wie viele Zeilen / Tabellen von ihr gesperrt werden usw. Schauen Sie unter TRANSACTIONS.

Das Problem bei der Verwendung SHOW PROCESSLISTist, dass die Sperren nur angezeigt werden, wenn andere Abfragen in der Warteschlange stehen.

Polymorphix
quelle
20

Versuchen Sie SHOW OPEN TABLES:

show open tables where In_Use > 0 ;
M Sleman
quelle
Ich denke, dies ist die beste Möglichkeit, in Gebrauch befindliche Sperren sofort zu identifizieren, insbesondere wenn Sie über mehrere Datenbanken und Hunderte von Verbindungen verfügen.
Nelaaro
7

Mit diesem Befehl

SHOW PROCESSLIST

Zeigt alle derzeit ausgeführten Prozesse an, einschließlich der Prozesse, für die die Tabellensperre aktiviert wurde.

Arie K
quelle
7

Keine der Antworten kann alle aktuell gehaltenen Sperren anzeigen.

Tun Sie dies zB in MySQL in einem Terminal.

start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there

Die obige Transaktion ist eindeutig gesperrt, da die Transaktion noch aktiv ist. Aber im Moment läuft keine Abfrage und niemand wartet irgendwo (zumindest noch) auf ein Schloss.

INFORMATION_SCHEMA.INNODB_LOCKSist leer, was angesichts der Dokumentation sinnvoll ist , da es nur eine Transaktion gibt und derzeit niemand auf Sperren wartet. Auch INNODB_LOCKSist veraltet sowieso.

SHOW ENGINE INNODB STATUSist nutzlos: someTablewird überhaupt nicht erwähnt

SHOW FULL PROCESSLIST ist leer, da der Täter gerade keine Abfrage ausführt.

Sie können verwendet werden INFORMATION_SCHEMA.INNODB_TRX, performance_schema.events_statements_historyund performance_schema.threadsdie Abfragen zu extrahieren , dass alle aktiven Transaktionen in der Vergangenheit durchgeführt haben , wie in skizzierte meine andere Antwort , aber ich habe nicht über irgendeine Art und Weise kommen , um zu sehen , dass someTablein dem obigen Szenario ist gesperrt.

Die Vorschläge in den anderen Antworten helfen zumindest nicht weiter.

Haftungsausschluss: Ich habe kein innotop installiert und habe mich nicht darum gekümmert. Vielleicht könnte das funktionieren.

Peter V. Mørch
quelle
6

AFAIK Es gibt noch keinen nativen Weg in MYSQL, aber ich benutze innotop . Es ist kostenlos und hat viele andere Funktionen.

Weitere Informationen zur Verwendung des Innotop-Tools finden Sie auch unter diesem Link .

Marko Carter
quelle
4

Referenz aus diesem Beitrag entnommen.

Sie können folgendes Skript verwenden:

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
Anvesh
quelle