MySQL: SQL-Abfragen protokollieren, einsehen und löschen

MySQL: SQL-Abfragen protokollieren, einsehen und löschen

MySQL-Abfragen lassen sich aus verschiedenen nicht immer in der Anwendung selbst ausgeben. Die zunehmende Verwendung von ORMs macht es nicht leichter, im Gegenteil: Hier bekommt nicht mal mehr der Entwickler die SQL-Abfragen im Quellcode zu Gesicht. Sicher gibt es je nach verwendetem Framework die Möglichkeit, auf dessen generierte Abfragen zuzugreifen. Diese muss man dann aber wiederum von Hand protokollieren. Die einfachste Möglichkeit besteht daher nicht selten darin, einfach den SQL-Server seine ausgeführten Abfragen einzusehen. Folgender Artikel zeigt, wie mit diesem Protokoll gearbeitet wird.

Durch das Aktivieren des Abfragenprotokolles wird der Server jede einzelne SQL-Abfrage speichern, wodurch erheblicher Overhead entstehen kann. Die Nutzung dieser Funktion auf Produktivsystemen, insbesondere mit hohem Traffic, verbietet sich somit. Man sollte dies nur auf einem (lokalen) Entwicklungssystem durchführen. 

MySQL Abfragen-Log aktivieren/deaktivieren

Standardmäßig protokolliert MySQL die Abfragen aus Performance-Gründen nicht. Am einfachsten aktiviert man diese durch das globale Setzen der Konfigurationsvariablen general_log. Mit log_output wird anschließend noch festgelegt, auf welche Art protokolliert werden soll. In diesem Falle nutzen wir eine Tabelle, da sich die Einträge so über Abfragen sortieren und ggf. Filtern lassen. Alternativ kann man auch eine Datei verwenden.

SET global log_output = 'table';
SET global general_log = 1;

Die Reihenfolge ist egal. Es macht allerdings Sinn, das Ziel vor dem Aktivieren festzulegen wie im Beispiel oben. Sobald general_log auf 1 gesetzt wurde, beginnt die Protokollierung. Ansonsten haben wir die zweite Abfragte unnötigerweise bereits in den Logs.

Ist die Analyse der Abfragen abgeschlossen, sollte man die Protokollierung wieder deaktivieren. Dazu genügt es, general_log auf 0 zu setzen:

SET global general_log = 0;

Protokollierte SQL-Abfragen einsehen

Sollen die Protokolle in der Datenbank gespeichert werden wie im Beispiel oben, können wir sie über eine Abfrage auf die Tabelle mysql.general_log einsehen. Für den Anfang am einfachsten mit der Abfrage

SELECT * 
FROM mysql.general_log;

Das Ergebnis sieht anfangs noch recht leer aus:

Ist die Log voller, kann man beispielsweise nach der Spalte event_time absteigend sortieren, um die neusten Einträge oben einzusehen. Die restlichen Spalten bieten bei Bedarf weitere Filtermöglichkeiten, auf die ich an dieser Stelle aber nicht weiter eingehen möchte. Folgende Abfrage zeigt etwa nur die geloggten Abfragen der letzten 10 Sekunden:

SELECT * 
FROM mysql.general_log
WHERE event_time > (NOW() - INTERVAL 10 SECOND)

auf die ich an dieser Stelle nicht weiter eingehen möchte.

Protokoll leeren

Mit der Zeit wird sich das Protokoll weiter füllen, obwohl man die vorherigen Abfragen zur aktuellen Diagnose vielleicht gar nicht mehr braucht. Hier bietet es sich an, das Protokoll zu leeren. Obwohl die Logs in einer normalen Tabelle gespeichert werden, lassen sie sich mit dem DELETE-Befehl nicht ohne weiteres entfernen. Dafür müssen wir uns eines kleinen Tricks bedienen, bei dem wir die Tabelle zur Leerung umbenennen:

SET GLOBAL general_log = 0;
RENAME TABLE mysql.general_log TO general_log_temp;
DELETE FROM general_log_temp WHERE 1;
RENAME TABLE general_log_temp TO mysql.general_log;

Das vorherige Deaktivieren verhindert Probleme durch neue Abfragen, die während dieses Vorganges eingehen. Soll MySQL danach direkt wieder weiter protokollieren, kann dies wie oben beschrieben wieder aktiviert werden.

Leave a Reply