Consigner toutes les requêtes dans mysql


279

Puis-je activer la journalisation d'audit sur ma base de données mysql?

Je veux essentiellement surveiller toutes les requêtes pendant une heure et vider le journal dans un fichier.


8
TMS

Pour le bénéfice des lecteurs: Ne manquez pas de lire la question dans le commentaire ci-dessus.
claws

Vous pouvez consulter ma réponse existante publiée ici dba.stackexchange.com/a/62477/6037
Peter Venderberghe

Réponses:


166

Démarrez mysql avec l'option --log:

mysqld --log=log_file_name

ou placez ce qui suit dans votre my.cnfdossier:

log = log_file_name

L'un ou l'autre enregistrera toutes les requêtes dans log_file_name.

Vous pouvez également consigner uniquement les requêtes lentes en utilisant l' --log-slow-queriesoption au lieu de --log. Par défaut, les requêtes qui prennent 10 secondes ou plus sont considérées comme lentes, vous pouvez changer cela en définissant long_query_timele nombre de secondes qu'une requête doit prendre pour s'exécuter avant d'être enregistrée.


61
Cela devrait aller de soi, mais laisser cela activé dans une boîte de production devient très rapidement non divertissant. g
ceejayoz

6
Si vous ne parvenez pas à activer la journalisation de cette manière, vérifiez à nouveau que l'utilisateur mysql peut écrire à l'emplacement de fichier approprié.
Jon Topper

3
Est-il possible d'enregistrer des requêtes sur une seule base de données / table particulière?
Temujin

2
@Temujin phpmyadmin a maintenant une option de «suivi» pour les tableaux où vous spécifiez un journal («version») et il gardera une trace des requêtes qui l'affectent avec des informations sur le temps et la requête entière.
gadget00

3
Cette réponse acceptée doit être supprimée ou modifiée pour refléter le fait qu'elle ne fonctionne pas avec MySQL 5.6. +.
itoctopus le

233

( Remarque : pour mysql-5.6 +, cela ne fonctionnera pas. Il existe une solution qui s'applique à mysql-5.6 + si vous faites défiler vers le bas ou cliquez ici .)

Si vous ne voulez pas ou ne pouvez pas redémarrer le serveur MySQL, vous pouvez procéder comme ceci sur votre serveur en cours d'exécution:

  • Créez vos tables de log sur la mysqlbase de données
  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'
  • Activer la journalisation des requêtes sur la base de données
SET global general_log = 1;
SET global log_output = 'table';
  • Afficher le journal
select * from mysql.general_log
  • Désactiver la journalisation des requêtes sur la base de données
SET global general_log = 0;

14
Je ne sais pas si cela est vrai pour chaque version de MySQL (je suis sur 5.5), mais je n'ai pas eu à créer les tables. J'ai suivi le même conseil moins la création des tables, qui est mentionné ici: stackoverflow.com/a/678310/135101
Tyler Collier

Peut-être qu'il a déjà été créé pour une raison ou une autre, @TylerCollier
Alexandre Marcondes

3
Il convient de noter que les CREATE TABLEcommandes doivent (si les tables n'existent pas déjà) être exécutées sur la mysqlbase de données, et non sur des bases de données créées par l'utilisateur. Peut-être que les instructions SQL pourraient être mises à jour pour refléter cela.
Robert Rossmann

2
Pour visualiser le journal SELECT * FROM mysql.general_log order by (event_time) descfera mieux. juste dire. :-)
vinrav

Ne pas être d'accord avec la note - avec la version 5.6.37 du serveur fonctionne parfaitement correctement. Merci.
Dmitriy Olhovsky

215

Outre ce que j'ai rencontré ici, l'exécution de ce qui suit était le moyen le plus simple de vider des requêtes dans un fichier journal sans redémarrer

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

peut être désactivé avec

SET global general_log = 0;

6
J'adore cela, fonctionne pour les connexions existantes et nouvelles sur la DB
Carlton

1
Il y avait quelques entrées de statistiques - je ne sais pas trop ce que c'est, sinon ça marche vraiment bien.
Snowcrash

Pour que cela fonctionne, votre utilisateur doit disposer du privilège SUPER, qui est un privilège de base de données global et ne peut donc pas être limité à des schémas ou des tables spécifiques:GRANT SUPER ON *.* TO user1@localhost
RobM

Je voterais plus d'une fois si je le pouvais, j'ai un signet pointant ici :) Merci beaucoup!
resi

125

La meilleure réponse ne fonctionne pas dans mysql 5.6+. Utilisez-le à la place:

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

dans votre fichier my.cnf / my.ini

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


1
Si vous l'avez utilisé, pouvez-vous me dire l'impact sur les performances de ce qui précède, et serait-il sage d'activer la journalisation de cette façon?
Ramesh Pareek

1
L'impact sur les performances de Ramesh semble être d'environ 5 à 15% de baisse des performances. Plus d'infos ici percona.com/blog/2009/02/10/…
Firze

1
Je ne comprends pas pourquoi Mysql 5.6 ne permet pas de définir le fichier journal à partir des requêtes? Comment enregistrer toutes les requêtes dans MySQL 5.6 et versions ultérieures lorsque vous n'avez pas accès à l'arborescence des répertoires du serveur mais uniquement phpMyAdmin?
Vicky Dev

redémarrez le service mysql à partir du panneau de configuration de xampp après ces modifications.
Paramjeet

Cela a fonctionné pour moi dans mon environnement Xampp Apache local, mais j'ai quand même dû activer la connexion via phpMyAdmin. En outre, il ne pouvait pas localiser le fichier dans le dossier / usr / log, ni le créer, mais cela fonctionnait très bien commegeneral_log_file=filename.log
JoeP

36

Activer le journal pour la table

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

Afficher le journal par requête de sélection

select * from mysql.general_log

existe-t-il un caractère générique pour enregistrer toutes les tables? (il y en a beaucoup: C)
RicardoE

Merci, ce paramètre m'a été très utile car je n'ai pas pu supprimer le serveur mysql. Je veux également que le journal apparaisse dans le journal de bord
Gunnar Sigfusson

14

Un moyen rapide d'activer MySQL General Query Log sans redémarrer.

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

J'ai installé mysql via homebrew, version mysql: mysql Ver 14.14 Distrib 5.7.15, pour osx10.11 (x86_64) en utilisant le wrapper EditLine


6

Pour mémoire, general_log et slow_log ont été introduits en 5.1.6:

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

5.2.1. Sélection des destinations de sortie du journal des requêtes générales et des requêtes lentes

Depuis MySQL 5.1.6, MySQL Server offre un contrôle flexible sur la destination de sortie vers le journal de requête général et le journal de requête lente, si ces journaux sont activés. Les destinations possibles pour les entrées de journal sont les fichiers journaux ou les tables general_log et slow_log dans la base de données mysql


5

Vous devez savoir que la connexion à mysql a vraiment un impact sur les performances, mais cela peut être une bonne chose à faire.

Je le laisse généralement allumé sur le serveur de développement (sauf quand cela nous rend fous :))


2

Version OS / 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

Ajout de la journalisation (par exemple, je ne pense pas que ce /var/log/...soit le meilleur chemin sur Mac OS mais cela a fonctionné:

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

Mysql redémarré

Résultat:

$ 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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.