Zaloguj wszystkie zapytania w mysql


279

Czy mogę włączyć rejestrowanie kontroli w mojej bazie danych mysql?

Zasadniczo chcę monitorować wszystkie zapytania przez godzinę i zrzucić dziennik do pliku.



Korzyści dla czytelników: nie przegap tego pytania w powyższym komentarzu.
pazury

Możesz odnieść się do mojej istniejącej odpowiedzi opublikowanej tutaj dba.stackexchange.com/a/62477/6037
Peter Venderberghe

Odpowiedzi:


165

Uruchom mysql z opcją --log:

mysqld --log=log_file_name

lub umieść w my.cnfpliku:

log = log_file_name

Każdy z nich rejestruje wszystkie zapytania do log_file_name.

Możesz także rejestrować tylko powolne zapytania, używając --log-slow-queriesopcji zamiast --log. Domyślnie zapytania trwające 10 sekund lub dłużej są uważane za wolne, można to zmienić, ustawiając long_query_timeliczbę sekund, przez które zapytanie musi zostać wykonane przed zalogowaniem.


61
Powinno to być oczywiste, ale pozostawienie tego włączonego w pudełku produkcyjnym szybko kończy się zabawą. g
ceejayoz

6
Jeśli masz problemy z włączeniem logowania w ten sposób, sprawdź dwukrotnie, czy użytkownik mysql może zapisać w odpowiedniej lokalizacji pliku.
Jon Topper,

3
Czy można rejestrować zapytania dotyczące tylko 1 db / tabeli?
Temujin

2
@Temujin phpmyadmin ma teraz opcję „śledzenia” dla tabel, w których określasz dziennik („wersję”), i będzie on rejestrował wpływające na niego zapytania wraz z informacją o czasie i całym zapytaniu.
gadget00,

3
Ta zaakceptowana odpowiedź powinna zostać usunięta lub poddana edycji, aby odzwierciedlić fakt, że nie działa z MySQL 5.6. +.
itoctopus

233

( Uwaga : w przypadku mysql-5.6 + to nie zadziała. Istnieje rozwiązanie, które dotyczy mysql-5.6 +, jeśli przewiniesz w dół lub klikniesz tutaj .)

Jeśli nie chcesz lub nie możesz zrestartować serwera MySQL, możesz postępować w ten sposób na uruchomionym serwerze:

  • Utwórz tabele dziennika w mysqlbazie danych
  CREATE TABLE `slow_log` (
   `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
                          ON UPDATE CURRENT_TIMESTAMP,
   `user_host` mediumtext NOT NULL,
   `query_time` time NOT NULL,
   `lock_time` time NOT NULL,
   `rows_sent` int(11) NOT NULL,
   `rows_examined` int(11) NOT NULL,
   `db` varchar(512) NOT NULL,
   `last_insert_id` int(11) NOT NULL,
   `insert_id` int(11) NOT NULL,
   `server_id` int(10) unsigned NOT NULL,
   `sql_text` mediumtext NOT NULL,
   `thread_id` bigint(21) unsigned NOT NULL
  ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
  CREATE TABLE `general_log` (
   `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
                          ON UPDATE CURRENT_TIMESTAMP,
   `user_host` mediumtext NOT NULL,
   `thread_id` bigint(21) unsigned NOT NULL,
   `server_id` int(10) unsigned NOT NULL,
   `command_type` varchar(64) NOT NULL,
   `argument` mediumtext NOT NULL
  ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
  • Włącz rejestrowanie zapytań w bazie danych
SET global general_log = 1;
SET global log_output = 'table';
  • Zobacz dziennik
select * from mysql.general_log
  • Wyłącz rejestrowanie zapytań w bazie danych
SET global general_log = 0;

14
Nie jestem pewien, czy dotyczy to każdej wersji MySQL (mam wersję 5.5), ale nie musiałem tworzyć tabel. Postępowałem zgodnie z tą samą radą, pomijając tworzenie tabel, o której tu wspomniano: stackoverflow.com/a/678310/135101
Tyler Collier

Może został już utworzony z jednego lub innego powodu, @TylerCollier
Alexandre Marcondes

3
Należy zauważyć, że CREATE TABLEpolecenia (jeśli tabele jeszcze nie istnieją) powinny być wykonywane w mysqlbazie danych, a nie w bazach danych utworzonych przez użytkowników. Być może instrukcje SQL mogłyby zostać zaktualizowane, aby to odzwierciedlić.
Robert Rossmann

2
Do przeglądania dziennika SELECT * FROM mysql.general_log order by (event_time) descbędzie lepiej. tylko mówię. :-)
vinrav

Nie zgadzaj się z uwagą - z wersją serwera 5.6.37 działa w pełni poprawnie. Dzięki.
Dmitriy Olhovsky,

215

Oprócz tego, co tu natknąłem, uruchomienie poniższego było najprostszym sposobem na zrzucenie zapytań do pliku dziennika bez ponownego uruchamiania

SET global log_output = 'FILE';
SET global general_log_file='/Applications/MAMP/logs/mysql_general.log';
SET global general_log = 1;

można wyłączyć za pomocą

SET global general_log = 0;

6
Absolutnie uwielbiam to, działa dla istniejących i nowych połączeń na DB
Carlton

1
Było kilka wpisów w statystykach - nie jestem pewien, co to są, ale w przeciwnym razie działa naprawdę dobrze.
Snowcrash

Aby to zadziałało, użytkownik musi mieć uprawnienie SUPER, które jest uprawnieniem globalnej bazy danych, a zatem nie może być ograniczone do określonych schematów lub tabel:GRANT SUPER ON *.* TO user1@localhost
RobM

Głosowałbym za tym więcej niż raz, gdybym mógł, mam zakładkę wskazującą tutaj :) Dziękuję bardzo!
resi

124

Najlepsza odpowiedź nie działa w mySQL 5.6+. Zamiast tego użyj tego:

[mysqld]
general_log = on
general_log_file=/usr/log/general.log

w pliku my.cnf / my.ini

Ubuntu / Debian : /etc/mysql/my.cnf
systemu Windows : C: \ ProgramData \ MySQL \ MySQL Server 5.x
wamp : c: \ wamp \ bin \ mysql \ mysqlx.yz \ my.ini
xampp : c: \ xampp \ mysql \ bin \ my.ini.


Jeśli z niego korzystałeś, czy możesz mi powiedzieć o wpływie powyższego na wydajność i czy rozsądnie byłoby włączyć rejestrowanie w ten sposób?
Ramesh Pareek

1
Wydaje się, że wpływ na wydajność Ramesha to około 5-15% spadek wydajności. Więcej informacji tutaj percona.com/blog/2009/02/10/…
Firze

1
Nie rozumiem, dlaczego Mysql 5.6 nie zezwala na ustawienie pliku dziennika na podstawie zapytań? Jak zalogować wszystkie zapytania w MySQL 5.6 i nowszych, gdy nie masz dostępu do drzewa katalogów serwera, ale tylko phpMyAdmin?
Vicky Dev,

uruchom ponownie usługę mysql z panelu sterowania xampp po tych zmianach.
Paramjeet,

Działa to dla mnie w moim lokalnym środowisku Xampp Apache, ale nadal musiałem włączyć logowanie przez phpMyAdmin. Ponadto nie mógł zlokalizować pliku w folderze / usr / log, ani go nie utworzył, ale działał dobrze, ponieważgeneral_log_file=filename.log
JoeP

36

Włącz dziennik dla tabeli

mysql> SET GLOBAL general_log = 'ON';
mysql> SET global log_output = 'table';

Wyświetl dziennik według wybranego zapytania

select * from mysql.general_log

czy istnieje znak wieloznaczny do rejestrowania wszystkich tabel? (jest ich całkiem sporo: C)
RicardoE,

Dzięki, to ustawienie było dla mnie bardzo przydatne, ponieważ nie mogłem zdjąć serwera mysql. Chcę również, aby dziennik pojawił się w dzienniku
Gunnar Sigfusson,

14

Szybki sposób na włączenie dziennika ogólnych zapytań MySQL bez ponownego uruchamiania.

mysql> SET GLOBAL general_log = 'ON';
mysql> SET GLOBAL general_log_file = '/var/www/nanhe/log/all.log';

Zainstalowałem mysql przez homebrew, wersja mysql: mysql Ver 14.14 Distrib 5.7.15, dla osx10.11 (x86_64) przy użyciu wrappera EditLine


6

Dla przypomnienia, general_log i slow_log zostały wprowadzone w 5.1.6:

http://dev.mysql.com/doc/refman/5.1/en/log-destinations.html

5.2.1 Wybieranie miejsc docelowych wyjściowych zapytań ogólnych i dzienników wolnych zapytań

Począwszy od MySQL 5.1.6, MySQL Server zapewnia elastyczną kontrolę nad miejscem docelowym danych wyjściowych do ogólnego dziennika zapytań i dziennika powolnych zapytań, jeśli dzienniki te są włączone. Możliwymi miejscami docelowymi dla wpisów dziennika są pliki dziennika lub tabele dzienników_ogólnych i dzienników_wolnych w bazie danych mysql


5

Należy pamiętać, że logowanie mysql naprawdę wpływa na wydajność, ale może to być mądre.

Zwykle zostawiam to włączone na serwerze deweloperskim (chyba że doprowadza nas to do szaleństwa :))


2

Wersja systemu operacyjnego / mysql:

$ uname -a
Darwin Raphaels-MacBook-Pro.local 15.6.0 Darwin Kernel Version 15.6.0: Thu Jun 21 20:07:40 PDT 2018; root:xnu-3248.73.11~1/RELEASE_X86_64 x86_64

$ mysql --version
/usr/local/mysql/bin/mysql  Ver 14.14 Distrib 5.6.23, for osx10.8 (x86_64) using  EditLine wrapper

Dodanie rejestrowania (na przykład nie sądzę, że /var/log/...jest to najlepsza ścieżka w systemie Mac OS, ale działało:

sudo vi ./usr/local/mysql-5.6.23-osx10.8-x86_64/my.cnf

[mysqld]
general_log = on
general_log_file=/var/log/mysql/mysqld_general.log

Zrestartowałem MySQL

Wynik:

$ sudo tail -f /var/log/mysql/mysqld_general.log
181210  9:41:04    21 Connect   root@localhost on employees
           21 Query /* mysql-connector-java-5.1.47 ( Revision: fe1903b1ecb4a96a917f7ed3190d80c049b1de29 ) */SELECT  @@session.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, @@character_set_connection AS character_set_connection, @@character_set_results AS character_set_results, @@character_set_server AS character_set_server, @@collation_server AS collation_server, @@collation_connection AS collation_connection, @@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, @@license AS license, @@lower_case_table_names AS lower_case_table_names, @@max_allowed_packet AS max_allowed_packet, @@net_buffer_length AS net_buffer_length, @@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, @@system_time_zone AS system_time_zone, @@time_zone AS time_zone, @@tx_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout
           21 Query SET NAMES latin1
           21 Query SET character_set_results = NULL
           21 Query SET autocommit=1
           21 Query SELECT USER()
           21 Query SELECT USER()
181210  9:41:10    21 Query show tables
181210  9:41:25    21 Query select count(*) from current_dept_emp

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.