Wie kann ich Live-MySQL-Abfragen anzeigen?


493

Wie kann ich MySQL-Abfragen auf meinem Linux-Server verfolgen, wenn sie auftreten?

Zum Beispiel würde ich gerne eine Art Listener einrichten, dann eine Webseite anfordern und alle Abfragen anzeigen, die die Engine ausgeführt hat, oder einfach alle Abfragen anzeigen, die auf einem Produktionsserver ausgeführt werden. Wie kann ich das machen?


Je nachdem, wie schlimm ein Problem ist, würde ich MySql Proxy wärmstens empfehlen. B / c kann es auf dem App-Server platziert werden, a) es ist skalierbar, b) muss nicht den gesamten Datenverkehr zur Datenbank beeinflussen. Es ist in 'Alpha', aber es gibt es schon lange. dev.mysql.com/downloads/mysql-proxy
Jeff Maass

15
Warum war das geschlossen?! Es wird gefragt, wie man X macht , nicht für eine Empfehlung. Fast 200 Menschen fanden diese Frage hilfreich. Die Mods müssen sich beruhigen.
Cerin

1
Ich habe diese Frage umformuliert, um Verweise auf Tools wegzulassen. Ich denke, diese Frage ist hier perfekt zum Thema: "Führen wir die Abfragen aus, die wir sein sollten?" ist ein guter erster Schritt beim Debuggen eines datenbankbezogenen Problems.
Jeffrey Bosboom

1
@ MaasSql MySQL-Proxy ist für PHP-Entwickler bei der Verwendung von PDO nicht hilfreich, da die Abfrage und die Werte nur auf dem Server gebunden werden.
Ananda

Antworten:


299

Sie können den MySQL-Befehl ausführen, um SHOW FULL PROCESSLIST;zu sehen, welche Abfragen zu einem bestimmten Zeitpunkt verarbeitet werden, aber das wird wahrscheinlich nicht das erreichen, was Sie sich erhoffen.

Die beste Methode, um einen Verlauf abzurufen, ohne jede Anwendung über den Server ändern zu müssen, sind wahrscheinlich Trigger. Sie können Trigger so einrichten, dass jeder Abfrageauslauf dazu führt, dass die Abfrage in eine Art Verlaufstabelle eingefügt wird, und dann eine separate Seite erstellen, um auf diese Informationen zuzugreifen.

Beachten Sie jedoch, dass dies wahrscheinlich alles auf dem Server erheblich verlangsamt, indem Sie zu INSERTjeder einzelnen Abfrage ein zusätzliches hinzufügen .


Bearbeiten: Eine andere Alternative ist das allgemeine Abfrageprotokoll. Wenn es jedoch in eine flache Datei geschrieben wird, werden viele Möglichkeiten für eine flexible Anzeige, insbesondere in Echtzeit, ausgeschlossen. Wenn Sie nur eine einfache, leicht zu implementierende Methode wünschen, um zu sehen, was los ist, reicht es aus, GQL zu aktivieren und dann die Protokolldatei auszuführen tail -f.


5
Das mag albern klingen, aber wie genau kann ich GQL aktivieren? Ich habe log_output = file, general_log = 1 und general_log_file = / pathtofile hinzugefügt und die Protokolldatei beendet, die Site aufgerufen und nichts erhalten. Was mache ich falsch?
Barfoon

Ich kann mir über nichts sicher sein, aber stellen Sie sicher, dass Sie den Server neu gestartet haben und dass die von Ihnen ausgewählte Datei eine Datei ist, auf die MySQL Schreibzugriff haben würde.
Chad Birch

7
Ich habe es herausgefunden - alles, was ich in my.cnf brauchte, war log = / path / to / log. Dann habe ich einfach den Schwanz drauf gemacht und es werden alle Abfragen angezeigt.
Barfoon

1
Soweit ich das beurteilen kann, gibt es keine Möglichkeit, eine SELECT-Anweisung auszulösen . Trigger gelten nur für INSERT, UPDATE, DELETE ... oder bin ich falsch informiert?
gabe.

1
Ich war früher an der gleichen Stelle. Derzeit verwende ich Monyog, das all dies mit sehr wenig Aufwand erledigt, daher verlangsamt sich nichts.

520

Sie können jede Abfrage ganz einfach in einer Protokolldatei protokollieren:

mysql> SHOW VARIABLES LIKE "general_log%";

+------------------+----------------------------+
| Variable_name    | Value                      |
+------------------+----------------------------+
| general_log      | OFF                        |
| general_log_file | /var/run/mysqld/mysqld.log |
+------------------+----------------------------+

mysql> SET GLOBAL general_log = 'ON';

Machen Sie Ihre Fragen (auf einer beliebigen Datenbank). Grep oder anderweitig untersuchen/var/run/mysqld/mysqld.log

Dann vergiss es nicht

mysql> SET GLOBAL general_log = 'OFF';

oder die Leistung sinkt und Ihre Festplatte füllt sich!


37
Gute Antwort! Sie können verwenden tail -f -n300 /var/run/mysqld/mysqld.log, um Ihre Protokolldatei live zu verfolgen
Claudio Bredfeldt

4
Beachten Sie, dass für diese Variablen MySQL 5.1.12 oder höher erforderlich ist. Vorher müssten Sie MySQL neu starten, um diese Einstellungen zu ändern.
jlh

Gibt es eine Möglichkeit, die parametrisierten Variablen in das Protokoll zu schreiben? Ich sehe, SELECT name FROM person where id=?aber ich weiß nicht was idist.
Jeff

SHOW VARIABLEShat bei mir nicht funktioniert. Funktioniert jedoch SELECT @@GLOBAL.general_log_file;gut. (MariaDB 10.1.9)
Phil Pirozhkov

1
wichtig - Sie müssen die Protokollausgabe mit überprüfen SHOW VARIABLES LIKE "log_output%". Wenn dies festgelegt ist table, werden die Protokolle in der Datenbank selbst gespeichert, die Tabelle mysql.general_lognicht im Dateisystem. Sie können es ändern file mitSET GLOBAL log_output = 'file';
Arnis Juraga

199

Obwohl eine Antwort bereits akzeptiert wurde, möchte ich die vielleicht einfachste Option vorstellen:

$ mysqladmin -u bob -p -i 1 processlist

Dadurch werden die aktuellen Abfragen jede Sekunde auf Ihrem Bildschirm gedruckt.

  • -u Der MySQL-Benutzer, unter dem Sie den Befehl ausführen möchten
  • -p Fordern Sie zur Eingabe Ihres Kennworts auf (damit Sie es nicht in einer Datei speichern müssen oder der Befehl in Ihrem Befehlsverlauf angezeigt wird).
  • i Das Intervall in Sekunden.
  • Verwenden Sie das --verboseFlag, um die vollständige Prozessliste anzuzeigen und die gesamte Abfrage für jeden Prozess anzuzeigen. (Danke, nmat )

Es gibt einen möglichen Nachteil: Schnelle Abfragen werden möglicherweise nicht angezeigt, wenn sie zwischen dem von Ihnen festgelegten Intervall ausgeführt werden. IE: Mein Intervall ist auf eine Sekunde festgelegt. Wenn eine Abfrage .02Sekunden dauert und zwischen Intervallen ausgeführt wird, wird sie nicht angezeigt.

Verwenden Sie diese Option vorzugsweise, wenn Sie schnell überprüfen möchten, ob Abfragen ausgeführt werden, ohne einen Listener oder etwas anderes einrichten zu müssen.


11
DAS ist die beste Lösung!
user1398287

3
Meiner Meinung nach ist dies die bessere Lösung, da Sie nicht jedes Mal eine neue MySQL-Verbindung zum Senden des Befehls verwenden, sondern stattdessen eine MySQL-Verbindung öffnen und damit die Show-Prozessliste senden.
Jose Nobile

@JoseNobile Wenn Sie die MySQL-Verbindung in Ihrem Adapter offen halten, spielt das keine Rolle. Meine Lösung ist nicht genau für OP geeignet, da meine Lösung nicht für die Verwendung in einem Adapter bereit ist. Es ist jedoch schnell und einfach.
halfpastfour.am

7
Sie können hinzufügen --verbose, um die vollständigen Abfragen zu sehen
nmat

2
Dies ist die Antwort, nach der ich gesucht habe. Es sollte als Antwort akzeptiert werden. Es ist auch die einfachste Antwort zu implementieren.
Chad

51

Führen Sie diese praktische SQL-Abfrage aus, um zu sehen, wie MySQL-Abfragen ausgeführt werden. Es kann von jeder beliebigen Umgebung aus ausgeführt werden, wann immer Sie möchten, ohne Codeänderungen oder Overhead. Möglicherweise ist eine Konfiguration der MySQL-Berechtigungen erforderlich, aber für mich läuft es nur ohne spezielle Einrichtung.

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep';

Der einzige Haken ist, dass Sie häufig Abfragen verpassen, die sehr schnell ausgeführt werden. Dies ist daher besonders nützlich bei länger laufenden Abfragen oder wenn der MySQL-Server Abfragen hat, die gesichert werden. Nach meiner Erfahrung ist dies genau der Zeitpunkt, an dem ich sie anzeigen möchte. " Live "Abfragen.

Sie können auch Bedingungen hinzufügen, um die SQL-Abfrage spezifischer zu gestalten.

zB Zeigt alle Abfragen an, die 5 Sekunden oder länger ausgeführt werden:

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND TIME >= 5;

zB Alle laufenden UPDATEs anzeigen:

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND INFO LIKE '%UPDATE %';

Ausführliche Informationen finden Sie unter: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html


17

Ich bin in einer bestimmten Situation, in der ich keine Berechtigungen zum Aktivieren der Anmeldung habe und keine Berechtigungen zum Anzeigen der Protokolle hätte, wenn sie aktiviert wären. Ich konnte keinen Trigger hinzufügen, hatte aber die Berechtigung, show processlist aufzurufen. Also habe ich mich nach besten Kräften bemüht und mir Folgendes ausgedacht:

Erstellen Sie ein Bash-Skript mit dem Namen "showqlprocesslist":

#!/bin/bash

while [ 1 -le 1 ]
do
         mysql --port=**** --protocol=tcp --password=**** --user=**** --host=**** -e "show processlist\G" | grep Info | grep -v processlist | grep -v "Info: NULL";
done

Führen Sie das Skript aus:

./showsqlprocesslist > showsqlprocesslist.out &

Beenden Sie die Ausgabe:

tail -f showsqlprocesslist.out

Bingo Bango. Obwohl es nicht gedrosselt ist, hat es nur 2-4% CPU auf den Boxen beansprucht, auf denen ich es ausgeführt habe. Ich hoffe vielleicht hilft das jemandem.


Ha! Lecker. Liebe es.
Darth Egregious

Es braucht eine gewisse Verzögerung, um zu viele ausführliche Ausgaben zu vermeiden. Siehe meine Bearbeitung bitte.
Slyx

@Slyx danke für den Vorschlag, einen Schlaf in die Schleife zu setzen. Wenn Sie jedoch nach kurzlebigen Abfragen suchen, die weniger Zeit als der Schlaf benötigen, werden Sie möglicherweise vermissen, wonach Sie suchen. Wenn Sie wirklich nur rechtzeitig nach einem Schnappschuss suchen, sollte dieser nicht in einer Schleife ausgeführt werden. Es sollte auch beachtet werden, dass dies möglicherweise immer noch sehr kurzlebige Abfragen übersehen kann.
Michael Krauklis

17

strace

Der schnellste Weg, um Live-MySQL / MariaDB-Abfragen zu sehen, ist die Verwendung des Debuggers. Unter Linux können Sie stracezum Beispiel Folgendes verwenden:

sudo strace -e trace=read,write -s 2000 -fp $(pgrep -nf mysql) 2>&1

Da es viele maskierte Zeichen gibt, können Sie die Ausgabe von strace durch Piping (fügen Sie einfach |zwischen diesen beiden Einzeilern hinzu) oben in den folgenden Befehl formatieren :

grep --line-buffered -o '".\+[^"]"' | grep --line-buffered -o '[^"]*[^"]' | while read -r line; do printf "%b" $line; done | tr "\r\n" "\275\276" | tr -d "[:cntrl:]" | tr "\275\276" "\r\n"

Sie sollten also ziemlich saubere SQL-Abfragen ohne Zeitaufwand sehen, ohne die Konfigurationsdateien zu berühren.

Dies ersetzt natürlich nicht die unten beschriebene Standardmethode zum Aktivieren von Protokollen (bei der der SQL Server neu geladen wird).

dtrace

Verwenden Sie MySQL-Tests, um die Live-MySQL-Abfragen anzuzeigen, ohne den Server zu berühren. Beispielskript:

#!/usr/sbin/dtrace -q
pid$target::*mysql_parse*:entry /* This probe is fired when the execution enters mysql_parse */
{
     printf("Query: %s\n", copyinstr(arg1));
}

Speichern Sie das obige Skript in einer Datei (wie watch.d) und führen Sie Folgendes aus:

pfexec dtrace -s watch.d -p $(pgrep -x mysqld)

Weitere Informationen : Erste Schritte mit DTracing MySQL

Gibbs MySQL Spyglass

Siehe diese Antwort .

Protokolle

Hier sind die Schritte, die für Entwicklungsvorschläge nützlich sind.

Fügen Sie diese Zeilen in Ihre ~/.my.cnfoder global ein my.cnf:

[mysqld]
general_log=1
general_log_file=/tmp/mysqld.log

Pfade: /var/log/mysqld.logoder /usr/local/var/log/mysqld.logfunktionieren möglicherweise auch abhängig von Ihren Dateiberechtigungen.

Starten Sie dann MySQL / MariaDB neu durch ( sudoggf. Präfix mit ):

killall -HUP mysqld

Dann überprüfen Sie Ihre Protokolle:

tail -f /tmp/mysqld.log

Wechseln Sie nach Abschluss general_logzu 0(damit Sie es in Zukunft verwenden können), entfernen Sie die Datei und starten Sie den SQL Server erneut : killall -HUP mysqld.


1
Sie müssen den Server nicht beenden, wenn Sie die general_logaus einer MySQL-Abfrage festlegen . Es wird begonnen, in die Datei zu schreiben, auf die verwiesen general_log_filewird.
Robert Brisita

15

Dies ist das einfachste Setup auf einem Linux-Ubuntu-Computer, auf das ich gestoßen bin. Verrückt, alle Anfragen live zu sehen.

Suchen und öffnen Sie Ihre MySQL-Konfigurationsdatei, normalerweise /etc/mysql/my.cnf unter Ubuntu. Suchen Sie nach dem Abschnitt "Protokollierung und Replikation".

#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.

log = /var/log/mysql/mysql.log

Kommentieren Sie einfach die Variable "log" aus, um die Protokollierung zu aktivieren. Starten Sie MySQL mit diesem Befehl neu:

sudo /etc/init.d/mysql restart

Jetzt können Sie mit der Überwachung der eingehenden Abfragen beginnen. Öffnen Sie ein neues Terminal und führen Sie diesen Befehl aus, um durch die Protokolldatei zu scrollen und gegebenenfalls den Pfad anzupassen.

tail -f /var/log/mysql/mysql.log

Führen Sie nun Ihre Anwendung aus. In Ihrem Terminalfenster werden die Datenbankabfragen angezeigt. (Stellen Sie sicher, dass das Scrollen und der Verlauf auf dem Terminal aktiviert sind.)

VON http://www.howtogeek.com/howto/database/monitor-all-sql-queries-in-mysql/


13

Über eine Befehlszeile können Sie Folgendes ausführen:

watch --interval=[your-interval-in-seconds] "mysqladmin -u root -p[your-root-pw] processlist | grep [your-db-name]"

Ersetzen Sie die Werte [x] durch Ihre Werte.

Oder noch besser:

 mysqladmin -u root -p -i 1 processlist;

1
Dies ist eigentlich ein sehr guter Ausschnitt, der nützlich sein könnte. Danke!
MGP

genau das, wonach ich gesucht habe !! Uhr muss separat installiert werden.
Tilo

12

Schauen Sie sich mtop an .


1
Ja, aber viel Glück bei der Installation auf Debian oder Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner

Hat es geschafft, es auf Debian zum Laufen zu bringen, aber es ist irgendwie wertlos, da es viele Abfragen übersieht. Ich kann sehen, dass der Abfragezähler ständig ansteigt, aber selten Abfragen anzeigt. Es sieht so aus, als würden nur die Abfragen angezeigt, die länger als ca. 1 Sekunde dauern.
Cobra_Fast

@Cobra_Fast klar auf der mtop Sourceforge-Seite angegeben: mtop (MySQL top) monitors a MySQL server showing the queries which are taking the most amount of time to complete. mtop.sourceforge.net Es ist manchmal sehr nützlich.
Ian Lewis

7

Ich habe versucht, dasselbe zu tun, und habe eine Lösung aus verschiedenen Beiträgen zusammengeschustert und eine kleine Konsolen-App erstellt, um den Live-Abfragetext auszugeben, während er in die Protokolldatei geschrieben wird. Dies war in meinem Fall wichtig, da ich Entity Framework mit MySQL verwende und in der Lage sein muss, das generierte SQL zu überprüfen.

Schritte zum Erstellen der Protokolldatei (einige Duplikate anderer Beiträge, der Einfachheit halber hier):

  1. Bearbeiten Sie die Datei unter:

    C:\Program Files (x86)\MySQL\MySQL Server 5.5\my.ini

    Fügen Sie "log = development.log" am Ende der Datei hinzu. (Beachten Sie, dass ich zum Speichern dieser Datei meinen Texteditor als Administrator ausführen musste.)

  2. Verwenden Sie die MySQL-Workbench, um eine Befehlszeile zu öffnen, und geben Sie das Kennwort ein.

    Führen Sie die folgenden Schritte aus, um die allgemeine Protokollierung zu aktivieren, mit der alle ausgeführten Abfragen aufgezeichnet werden:

    SET GLOBAL general_log = 'ON';
    
    To turn off:
    
    SET GLOBAL general_log = 'OFF';

    Dadurch werden laufende Abfragen an der folgenden Stelle in eine Textdatei geschrieben.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
  3. Erstellen / Ausführen einer Konsolen-App, die die Protokollinformationen in Echtzeit ausgibt:

    Quelle hier zum Download verfügbar

    Quelle:

    using System;
    using System.Configuration;
    using System.IO;
    using System.Threading;
    
    namespace LiveLogs.ConsoleApp
    {
      class Program
      {
        static void Main(string[] args)
        {
            // Console sizing can cause exceptions if you are using a 
            // small monitor. Change as required.
    
            Console.SetWindowSize(152, 58);
            Console.BufferHeight = 1500;
    
            string filePath = ConfigurationManager.AppSettings["MonitoredTextFilePath"];
    
            Console.Title = string.Format("Live Logs {0}", filePath);
    
            var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
    
            // Move to the end of the stream so we do not read in existing
            // log text, only watch for new text.
    
            fileStream.Position = fileStream.Length;
    
            StreamReader streamReader;
    
            // Commented lines are for duplicating the log output as it's written to 
            // allow verification via a diff that the contents are the same and all 
            // is being output.
    
            // var fsWrite = new FileStream(@"C:\DuplicateFile.txt", FileMode.Create);
            // var sw = new StreamWriter(fsWrite);
    
            int rowNum = 0;
    
            while (true)
            {
                streamReader = new StreamReader(fileStream);
    
                string line;
                string rowStr;
    
                while (streamReader.Peek() != -1)
                {
                    rowNum++;
    
                    line = streamReader.ReadLine();
                    rowStr = rowNum.ToString();
    
                    string output = String.Format("{0} {1}:\t{2}", rowStr.PadLeft(6, '0'), DateTime.Now.ToLongTimeString(), line);
    
                    Console.WriteLine(output);
    
                    // sw.WriteLine(output);
                }
    
                // sw.Flush();
    
                Thread.Sleep(500);
            }
        }
      }
    }

1
Das sieht wirklich cool aus und ich werde es mir auf jeden Fall ansehen. Es ist großartig, dies als OSS-Projekt zu übernehmen und ein Profiling-Tool zu erstellen!
Rippo

Ich denke das ist eine gute Idee. Ich habe ein SVN-Repo auf Google-Code gesetzt. Wahrscheinlich das kleinste Betriebssystemprojekt aller Zeiten, aber dies war bisher sehr nützlich. Ich werde es wahrscheinlich erweitern, interessiert sein, ob jemand anderes es weiterführt. code.google.com/p/livelogs
gb2d

OP benötigt es, um auf seinem Linux-Computer zu arbeiten. Ihre Antwort ist anscheinend für einen Windows-Computer gedacht. Obwohl diese Antwort Kreativität widerspiegelt, ist sie für andere möglicherweise nicht hilfreich.
halfpastfour.am

1

Zusätzlich zu früheren Antworten, in denen beschrieben wurde, wie die allgemeine Protokollierung aktiviert wird, musste ich eine zusätzliche Variable in meiner Vanilla MySql 5.6-Installation ändern, bevor SQL in das Protokoll geschrieben wurde:

SET GLOBAL log_output = 'FILE';

Die Standardeinstellung war 'NONE'.


0

Gibbs MySQL Spyglass

AgilData hat kürzlich den Gibbs MySQL Scalability Advisor (ein kostenloses Self-Service-Tool) veröffentlicht, mit dem Benutzer einen Live-Stream von Abfragen erfassen können, die auf Gibbs hochgeladen werden sollen. Fernglas (Open Source) überwacht die Interaktionen zwischen Ihren MySQL-Servern und Clientanwendungen. Es ist keine Neukonfiguration oder kein Neustart des MySQL-Datenbankservers erforderlich (weder Client noch App).

GitHub: AgilData / gibbs-mysql-spyglass

Erfahren Sie mehr: Informationen Packet Capturing MySQL mit Rust

Installationsbefehl:

curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash

2
Spyglass scheint einen API-Schlüssel von einem Server zu benötigen, der nicht verfügbar ist, und das letzte Commit war vor 3 Jahren. Ich bin mir nicht sicher, ob dieses Produkt noch unterstützt wird / funktioniert.
Dan Tenenbaum
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.