Jak mogę wyświetlić zapytania MySQL na żywo?


492

Jak mogę śledzić zapytania MySQL na moim serwerze Linux, gdy się pojawiają?

Na przykład chciałbym skonfigurować jakiś odbiornik, a następnie poprosić o stronę internetową i wyświetlić wszystkie zapytania wykonane przez silnik lub po prostu wyświetlić wszystkie zapytania uruchamiane na serwerze produkcyjnym. W jaki sposób mogę to zrobić?


W zależności od tego, jak poważny jest problem, zdecydowanie polecam wypróbowanie MySql Proxy. B / c można go umieścić na serwerze aplikacji, a) jest skalowalny, b) nie musi wpływać na cały ruch do bazy danych. Jest w „alfa”, ale jest już od dłuższego czasu. dev.mysql.com/downloads/mysql-proxy
Jeff Maass

15
Dlaczego to było zamknięte ?! Pyta, jak zrobić X , a nie o rekomendacje. Prawie 200 osób uznało to pytanie za przydatne. Mody muszą się uspokoić.
Cerin

1
Przeredagowałem to pytanie, aby pominąć wszelkie odniesienia do narzędzi. Myślę, że to pytanie jest tutaj doskonale na temat, ponieważ „czy prowadzimy zapytania, którymi powinniśmy być?” to świetny pierwszy krok w debugowaniu problemu związanego z bazą danych.
Jeffrey Bosboom

1
@MaasSql mysql proxy nie jest pomocny dla programistów php podczas używania PDO, ponieważ zapytanie i wartości są powiązane tylko na serwerze.
Ananda,

Odpowiedzi:


298

Możesz uruchomić polecenie MySQL, SHOW FULL PROCESSLIST;aby zobaczyć, jakie zapytania są przetwarzane w danym momencie, ale prawdopodobnie nie osiągniesz tego, na co liczysz.

Najlepszą metodą uzyskania historii bez konieczności modyfikowania każdej aplikacji korzystającej z serwera są prawdopodobnie wyzwalacze. Można skonfigurować wyzwalacze, aby każde uruchomienie zapytania powodowało wstawienie zapytania do jakiejś tabeli historii, a następnie utworzyć osobną stronę, aby uzyskać dostęp do tych informacji.

Pamiętaj jednak, że prawdopodobnie znacznie spowolni to wszystko na serwerze, dodając dodatkowo INSERTdo każdego zapytania.


Edycja: inną alternatywą jest Ogólny dziennik zapytań , ale zapisanie go do płaskiego pliku wyeliminowałoby wiele możliwości elastycznego wyświetlania, szczególnie w czasie rzeczywistym. Jeśli chcesz po prostu prostego, łatwego do wdrożenia sposobu, aby zobaczyć, co się dzieje, włączenie GQL, a następnie użycie uruchamiania tail -fna pliku dziennika załatwi sprawę .


5
Może to zabrzmieć głupio, ale jak dokładnie mogę włączyć GQL? Dodałem log_output = plik, log_ogólny = 1 i plik_log_ogólny = / ścieżka_pliku, i poprawiłem plik dziennika, trafiłem na stronę i nic nie dostałem. Co ja robię źle?
barfoon

Nie mogę być niczego pewien, ale upewnij się, że zrestartowałeś serwer, a także, że wybrany plik to taki, do którego mysql miałby dostęp do zapisu.
Chad Birch

7
Zrozumiałem - wszystko, czego potrzebowałem w moim pliku. Cnf to log = / path / to / log Następnie zrobiłem na tym ogon i wyświetla wszystkie zapytania.
barfoon

1
O ile mi wiadomo, nie ma sposobu na wywołanie czegokolwiek w instrukcji SELECT. Wyzwalacze dotyczą tylko INSERT, UPDATE, DELETE ... czy jestem źle poinformowany?
Gabe.

1
Byłem wcześniej w tym samym miejscu. Obecnie używam Monyoga, który robi to wszystko z bardzo małym obciążeniem, dlatego nic nie zwalnia.

518

Możesz bardzo łatwo zapisać każde zapytanie do pliku dziennika:

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';

Wykonuj zapytania (na dowolnym db). Grep lub w inny sposób zbadaj/var/run/mysqld/mysqld.log

Więc nie zapomnij

mysql> SET GLOBAL general_log = 'OFF';

lub wydajność spadnie, a dysk się zapełni!


37
Dobra odpowiedź! Możesz użyć tail -f -n300 /var/run/mysqld/mysqld.logdo śledzenia pliku dziennika
Claudio Bredfeldt

4
Zauważ, że MySQL 5.1.12 lub wyższy jest wymagany dla tych zmiennych. Wcześniej musisz ponownie uruchomić MySQL, aby zmienić te ustawienia.
jlh

Czy jest jakiś sposób na zapisanie sparametryzowanych zmiennych do dziennika? Widzę, SELECT name FROM person where id=?ale nie wiem co idjest.
Jeff

SHOW VARIABLESnie działało dla mnie. Jednak SELECT @@GLOBAL.general_log_file;działa dobrze. (MariaDB 10.1.9)
phil pirozhkov

1
ważne - należy sprawdzić dane wyjściowe rejestrowania za pomocą SHOW VARIABLES LIKE "log_output%". Jeśli jest ustawiony na table, dzienniki będą zapisywane w samej bazie danych, tabela mysql.general_lognie w systemie plików. Możesz to zmienić za file pomocąSET GLOBAL log_output = 'file';
Arnis Juraga

199

Mimo że odpowiedź została już zaakceptowana, chciałbym przedstawić, co może być najprostszą opcją:

$ mysqladmin -u bob -p -i 1 processlist

Spowoduje to wydrukowanie bieżących zapytań na ekranie co sekundę.

  • -u Użytkownik mysql, który chcesz wykonać jako polecenie
  • -p Monituj o hasło (więc nie musisz go zapisywać w pliku ani wyświetlać polecenia w historii poleceń)
  • i Interwał w sekundach.
  • Użyj --verboseflagi, aby wyświetlić pełną listę procesów, wyświetlając całe zapytanie dla każdego procesu. (Dzięki, nmat )

Możliwy jest minus: szybkie zapytania mogą się nie pojawiać, jeśli będą działały między skonfigurowanym interwałem. IE: Mój interwał jest ustawiony na jedną sekundę i jeśli istnieje zapytanie, którego .02uruchomienie zajmuje kilka sekund i jest uruchamiane między interwałami, nie zobaczysz go.

Użyj tej opcji najlepiej, gdy chcesz szybko sprawdzać uruchomione zapytania bez konieczności konfigurowania detektora lub czegokolwiek innego.


11
To jest najlepsze rozwiązanie!
user1398287,

3
Moim zdaniem to lepsze rozwiązanie, ponieważ nie używaj nowego połączenia mysql do wysyłania polecenia za każdym razem, zamiast tego otwórz jedno połączenie mysql i użyj tego, aby wysłać listę procesów;
Jose Nobile

@JoseNobile Jeśli utrzymasz otwarte połączenie mysql w adapterze, to tak naprawdę nie ma znaczenia. Moje rozwiązanie nie jest odpowiednie dla OP, ponieważ moje rozwiązanie nie jest gotowe do użycia w adapterze. Jest to jednak szybkie i łatwe.
halfpastfour.am

7
Możesz dodać, --verboseaby zobaczyć pełne zapytania
nmat,

2
To była odpowiedź, której szukałem. Należy przyjąć jako odpowiedź. Jest to również najłatwiejsza odpowiedź do wdrożenia.
Czad

51

Uruchom to wygodne zapytanie SQL, aby zobaczyć uruchomione zapytania MySQL. Może być uruchamiany z dowolnego środowiska, które ci się podoba, kiedy tylko chcesz, bez żadnych zmian kodu ani kosztów ogólnych. Może wymagać pewnej konfiguracji uprawnień MySQL, ale dla mnie działa po prostu bez specjalnej konfiguracji.

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

Jedynym haczykiem jest to, że często pomijasz zapytania, które wykonują się bardzo szybko, więc jest to najbardziej przydatne w przypadku zapytań o dłuższym czasie działania lub gdy serwer MySQL zawiera zapytania, których kopie zapasowe są tworzone - z mojego doświadczenia wynika, że ​​właśnie wtedy chcę wyświetlić „ zapytania na żywo.

Możesz także dodać warunki, aby uczynić go bardziej szczegółowym dla dowolnego zapytania SQL.

np. pokazuje wszystkie zapytania działające przez 5 sekund lub dłużej:

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

np. Pokaż wszystkie uruchomione aktualizacje:

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

Aby uzyskać szczegółowe informacje, patrz: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html


17

Jestem w szczególnej sytuacji, w której nie mam uprawnień do włączania logowania i nie miałbym uprawnień do przeglądania dzienników, gdyby były włączone. Nie mogłem dodać wyzwalacza, ale miałem uprawnienia do wywoływania show list procesów. Dałem z siebie wszystko i wymyśliłem:

Utwórz skrypt bash o nazwie „showsqlprocesslist”:

#!/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

Uruchom skrypt:

./showsqlprocesslist > showsqlprocesslist.out &

Ogon wyjściowy:

tail -f showsqlprocesslist.out

Bingo bango. Mimo że nie jest dławiony, zajmuje tylko 2-4% procesora na urządzeniach, na których go uruchomiłem. Mam nadzieję, że to może komuś pomóc.


Ha! Pyszne. Kocham to.
Darth Egregious

Potrzebuje trochę opóźnienia, aby uniknąć zbyt dużej ilości danych wyjściowych. Zobacz moją Edycję, proszę.
Slyx

@Slyx dziękuje za sugestię, aby położyć sen w pętli. Jeśli jednak szukasz krótkotrwałych zapytań, które żyją krócej niż przez sen, potencjalnie przegapisz to, czego szukasz. Jeśli naprawdę szukasz migawki w czasie, nie powinno się jej uruchamiać w pętli. Należy również zauważyć, że może to potencjalnie przeoczyć bardzo krótkotrwałe zapytania.
Michael Krauklis

17

strace

Najszybszym sposobem na sprawdzenie zapytań MySQL / MariaDB na żywo jest użycie debuggera. W systemie Linux możesz użyć stracena przykład:

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

Ponieważ istnieje wiele znaków zmiany znaczenia, możesz sformatować dane wyjściowe strace przez potokowanie (wystarczy dodać |między tymi dwoma liniami) powyżej do następującego polecenia:

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"

Powinieneś więc widzieć dość czyste zapytania SQL bez czasu, bez dotykania plików konfiguracyjnych.

Oczywiście nie zastąpi to standardowego sposobu włączania dzienników, który jest opisany poniżej (co wymaga ponownego ładowania serwera SQL).

dtrace

Użyj sond MySQL do przeglądania zapytań MySQL na żywo bez dotykania serwera. Przykładowy skrypt:

#!/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));
}

Zapisz powyższy skrypt w pliku (jak watch.d) i uruchom:

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

Dowiedz się więcej: Rozpoczęcie pracy z DTracing MySQL

Gibbs MySQL Spyglass

Zobacz tę odpowiedź .

Kłody

Oto kroki przydatne przy projektowaniu.

Dodaj te linie do swojego ~/.my.cnflub globalnego my.cnf:

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

Ścieżki: /var/log/mysqld.loglub /usr/local/var/log/mysqld.logmoże również działać w zależności od uprawnień do plików.

następnie ponownie uruchom MySQL / MariaDB przez (przedrostek, sudojeśli to konieczne):

killall -HUP mysqld

Następnie sprawdź swoje dzienniki:

tail -f /tmp/mysqld.log

Po zakończeniu, zmiany general_logdo 0(dzięki czemu można go używać w przyszłości), a następnie usunąć plik i restart serwera SQL ponownie: killall -HUP mysqld.


1
Nie musisz zabijać serwera, jeśli ustawisz general_logz zapytania MySQL. Zacznie zapisywać do pliku, który general_log_filewskazuje.
Robert Brisita,

15

To najłatwiejsza konfiguracja na maszynie z systemem Linux Ubuntu, z którą się zetknąłem. Szalony, widząc wszystkie zapytania na żywo.

Znajdź i otwórz plik konfiguracyjny MySQL, zwykle /etc/mysql/my.cnf na Ubuntu. Poszukaj sekcji „Logowanie i replikacja”

#
# * 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

Po prostu odkomentuj zmienną „log”, aby włączyć rejestrowanie. Uruchom ponownie MySQL za pomocą tego polecenia:

sudo /etc/init.d/mysql restart

Teraz jesteśmy gotowi, aby rozpocząć monitorowanie zapytań w miarę ich pojawiania się. Otwórz nowy terminal i uruchom to polecenie, aby przewinąć plik dziennika, w razie potrzeby dostosowując ścieżkę.

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

Teraz uruchom aplikację. Zobaczysz, jak zapytania bazy danych zaczynają latać w oknie terminala. (upewnij się, że masz włączone przewijanie i historię na terminalu)

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


13

Z wiersza poleceń można uruchomić:

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

Zamień wartości [x] na swoje wartości.

Lub nawet lepiej:

 mysqladmin -u root -p -i 1 processlist;

1
To naprawdę bardzo dobry fragment, który może się przydać .. Dzięki!
MGP

dokładnie to, czego szukałem !! zegarek należy zainstalować osobno.
Tilo,

12

Sprawdź mtop .


1
Tak, ale powodzenia w instalacji na Debianie lub Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner

Udało mu się uruchomić go na Debianie, ale jest to bezwartościowe, ponieważ brakuje wielu zapytań. Widzę, że licznik zapytań stale rośnie, ale rzadko wyświetla zapytania. Wygląda na to, że wyświetla tylko zapytania trwające dłużej niż około 1 sekundy.
Cobra_Fast

@Cobra_Fast wyraźnie zaznaczono na stronie mtop Sourceforge: mtop (MySQL top) monitors a MySQL server showing the queries which are taking the most amount of time to complete. mtop.sourceforge.net Czasami jest to dość przydatne.
Ian Lewis

7

Chciałem zrobić to samo i stworzyłem rozwiązanie z różnych postów, a także stworzyłem małą aplikację konsolową do wyświetlania tekstu zapytania na żywo, gdy jest zapisywany w pliku dziennika. Było to ważne w moim przypadku, ponieważ używam Entity Framework z MySQL i muszę mieć możliwość sprawdzenia wygenerowanego SQL.

Kroki, aby utworzyć plik dziennika (niektóre powielanie innych postów, wszystko dla uproszczenia):

  1. Edytuj plik znajdujący się w:

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

    Dodaj „log = development.log” na dole pliku. (Uwaga: zapisanie tego pliku wymagało ode mnie uruchomienia edytora tekstów jako administrator).

  2. Użyj MySql workbench, aby otworzyć wiersz poleceń, wprowadź hasło.

    Uruchom następujące polecenie, aby włączyć rejestrowanie ogólne, które będzie rejestrować wszystkie uruchomione zapytania:

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

    Spowoduje to, że uruchomione zapytania zostaną zapisane w pliku tekstowym w następującej lokalizacji.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
  3. Utwórz / uruchom aplikację konsoli, która wyświetli informacje dziennika w czasie rzeczywistym:

    Źródło dostępne do pobrania tutaj

    Źródło:

    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
Wygląda to naprawdę fajnie i na pewno przyjrzę się temu, wspaniale będzie wziąć to jako projekt OSS i stworzyć narzędzie do profilowania!
Rippo

Myślę, że to dobry pomysł. Umieściłem repozytorium SVN w kodzie Google. Prawdopodobnie najmniejszy projekt systemu operacyjnego, ale jak dotąd był to bardzo użyteczny. Prawdopodobnie go przedłużę, zainteresuje mnie to, czy ktokolwiek pójdzie dalej. code.google.com/p/livelogs
gb2d

OP potrzebuje go do pracy na swoim komputerze z systemem Linux. Wygląda na to, że twoja odpowiedź jest przeznaczona dla komputera z systemem Windows. Chociaż ta odpowiedź odzwierciedla kreatywność, może nie być pomocna dla innych.
halfpastfour.am

1

Oprócz poprzednich odpowiedzi opisujących, jak włączyć rejestrowanie ogólne, musiałem zmodyfikować jedną dodatkową zmienną w mojej waniliowej instalacji MySql 5.6, zanim jakikolwiek SQL został zapisany w dzienniku:

SET GLOBAL log_output = 'FILE';

Domyślne ustawienie to „BRAK”.


0

Gibbs MySQL Spyglass

Firma AgilData uruchomiła niedawno narzędzie Gibbs MySQL Scalability Advisor (bezpłatne narzędzie samoobsługowe), które umożliwia użytkownikom przechwytywanie strumienia zapytań na żywo, które należy przesłać do Gibbs. Spyglass (czyli Open Source) będzie obserwował interakcje między Twoimi serwerami MySQL a aplikacjami klienckimi. Nie jest wymagana ponowna konfiguracja ani restartowanie serwera bazy danych MySQL (klienta ani aplikacji).

GitHub: AgilData / gibbs-mysql-spyglass

Dowiedz się więcej: Przechwytywanie pakietów MySQL za pomocą Rust

Polecenie instalacji:

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

2
Wygląda na to, że Spyglass wymaga klucza API z serwera, który jest wyłączony, a ostatnie zatwierdzenie miało miejsce 3 lata temu. Nie jestem pewien, czy ten produkt jest nadal obsługiwany / działa.
Dan Tenenbaum
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.