{"id":4337,"date":"2016-08-17T23:05:49","date_gmt":"2016-08-17T22:05:49","guid":{"rendered":"https:\/\/u-labs.de\/portal\/?p=4337"},"modified":"2016-08-17T23:05:49","modified_gmt":"2016-08-17T22:05:49","slug":"mysql-sql-abfragen-protokollieren-einsehen-und-loeschen","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/mysql-sql-abfragen-protokollieren-einsehen-und-loeschen\/","title":{"rendered":"MySQL: SQL-Abfragen protokollieren, einsehen und l\u00f6schen"},"content":{"rendered":"<p>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\u00f6glichkeit, auf dessen generierte Abfragen zuzugreifen. Diese muss man dann aber wiederum von Hand protokollieren. Die einfachste M\u00f6glichkeit besteht daher nicht selten darin, einfach den SQL-Server seine ausgef\u00fchrten Abfragen einzusehen. Folgender Artikel zeigt, wie mit diesem Protokoll gearbeitet wird.<\/p>\n<p><strong>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\u00fchren.\u00a0<\/strong><\/p>\n<h4><strong>MySQL Abfragen-Log aktivieren\/deaktivieren<\/strong><\/h4>\n<p>Standardm\u00e4\u00dfig protokolliert MySQL die Abfragen aus Performance-Gr\u00fcnden nicht. Am einfachsten aktiviert man diese durch das globale Setzen der Konfigurationsvariablen\u00a0<strong>general_log<\/strong>. Mit\u00a0<strong>log_output<\/strong> wird anschlie\u00dfend noch festgelegt, auf welche Art protokolliert werden soll. In diesem Falle nutzen wir eine Tabelle, da sich die Eintr\u00e4ge so \u00fcber Abfragen sortieren und ggf. Filtern lassen. Alternativ kann man auch eine Datei verwenden.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSET global log_output = 'table';\r\nSET global general_log = 1;\r\n<\/pre>\n<p>Die Reihenfolge ist egal. Es macht allerdings Sinn, das Ziel vor dem Aktivieren festzulegen wie im Beispiel oben. Sobald <strong>general_log<\/strong> auf <strong>1<\/strong> gesetzt wurde, beginnt die Protokollierung. Ansonsten haben wir die zweite Abfragte unn\u00f6tigerweise bereits in den Logs.<\/p>\n<p>Ist die Analyse der Abfragen abgeschlossen, sollte man die Protokollierung wieder deaktivieren. Dazu gen\u00fcgt es, general_log auf 0 zu setzen:<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSET global general_log = 0;\r\n<\/pre>\n<h4><strong>Protokollierte SQL-Abfragen einsehen<\/strong><\/h4>\n<p>Sollen die Protokolle in der Datenbank gespeichert werden wie im Beispiel oben, k\u00f6nnen wir sie \u00fcber eine Abfrage auf die Tabelle\u00a0<strong>mysql.general_log<\/strong> einsehen. F\u00fcr den Anfang am einfachsten mit der Abfrage<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT * \r\nFROM mysql.general_log;\r\n<\/pre>\n<p>Das Ergebnis sieht anfangs noch recht leer aus:<\/p>\n<p><a href=\"https:\/\/u-img.net\/img\/2634Km.jpg\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/u-img.net\/img\/2634Km.jpg\" \/><\/a><\/p>\n<p>Ist die Log voller, kann man beispielsweise nach der Spalte\u00a0<strong>event_time<\/strong> absteigend sortieren, um die neusten Eintr\u00e4ge oben einzusehen. Die restlichen Spalten bieten bei Bedarf weitere Filterm\u00f6glichkeiten, auf die ich an dieser Stelle aber nicht weiter eingehen m\u00f6chte. Folgende Abfrage zeigt etwa nur die geloggten Abfragen der letzten 10 Sekunden: <\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT * \r\nFROM mysql.general_log\r\nWHERE event_time &gt; (NOW() - INTERVAL 10 SECOND)\r\n<\/pre>\n<p> auf die ich an dieser Stelle nicht weiter eingehen m\u00f6chte.<\/p>\n<h4><strong>Protokoll leeren<\/strong><\/h4>\n<p>Mit der Zeit wird sich das Protokoll weiter f\u00fcllen, 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\u00a0<em>normalen<\/em> Tabelle gespeichert werden, lassen sie sich mit dem DELETE-Befehl nicht ohne weiteres entfernen. Daf\u00fcr m\u00fcssen wir uns eines kleinen Tricks bedienen, bei dem wir die Tabelle zur Leerung umbenennen:<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSET GLOBAL general_log = 0;\r\nRENAME TABLE mysql.general_log TO general_log_temp;\r\nDELETE FROM general_log_temp WHERE 1;\r\nRENAME TABLE general_log_temp TO mysql.general_log;\r\n<\/pre>\n<p>Das vorherige Deaktivieren verhindert Probleme durch neue Abfragen, die w\u00e4hrend dieses Vorganges eingehen. Soll MySQL danach direkt wieder weiter protokollieren, kann dies wie oben beschrieben wieder aktiviert werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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\u00f6glichkeit, auf dessen generierte Abfragen zuzugreifen. Diese muss man dann aber &#8230;<\/p>\n","protected":false},"author":5,"featured_media":4351,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[61],"tags":[339,58],"class_list":["post-4337","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-softwareentwicklung","tag-mysql","tag-sql"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/4337","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/comments?post=4337"}],"version-history":[{"count":13,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/4337\/revisions"}],"predecessor-version":[{"id":4350,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/4337\/revisions\/4350"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/4351"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=4337"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=4337"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=4337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}