web-dev-qa-db-fra.com

Comment afficher les requêtes MySQL en direct?

Comment puis-je suivre les requêtes MySQL sur mon serveur Linux au fur et à mesure qu'elles se produisent?

Par exemple, j'aimerais beaucoup configurer une sorte d'écouteur, puis demander une page Web et afficher toutes les requêtes exécutées par le moteur, ou simplement afficher toutes les requêtes en cours d'exécution sur un serveur de production. Comment puis-je faire ceci?

431
barfoon

Vous pouvez exécuter la commande MySQL SHOW FULL PROCESSLIST; pour voir quelles requêtes sont traitées à un moment donné, mais cela ne donnera probablement pas ce que vous espérez.

La meilleure méthode pour obtenir un historique sans avoir à modifier chaque application utilisant le serveur consiste probablement à utiliser des déclencheurs. Vous pouvez configurer des déclencheurs pour que chaque requête exécutée ait pour résultat l'insertion de la requête dans une sorte de table d'historique, puis créer une page distincte pour accéder à ces informations.

Sachez toutefois que cela ralentira probablement considérablement tout le contenu du serveur, avec l'ajout d'une variable INSERT supplémentaire à chaque requête.


Edit: une autre alternative est le General Query Log , mais l’écrire dans un fichier plat supprimerait beaucoup de possibilités de souplesse d’affichage, en particulier en temps réel. Si vous voulez simplement un moyen simple et facile d'implémenter de voir ce qui se passe, activer le GQL puis utiliser l'exécution de tail -f sur le fichier journal suffirait.

258
Chad Birch

Vous pouvez enregistrer chaque requête dans un fichier journal très facilement:

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

Faites vos requêtes (sur n'importe quelle base). Grep ou autrement examiner /var/run/mysqld/mysqld.log 

Alors n'oublie pas de 

mysql> SET GLOBAL general_log = 'OFF';

ou la performance va s'effondrer et votre disque va se remplir!

460
artfulrobot

Même si une réponse a déjà été acceptée, je voudrais présenter ce qui pourrait même être l'option la plus simple:

$ mysqladmin -u bob -p -i 1 processlist

Cela imprimera les requêtes actuelles sur votre écran toutes les secondes.

  • -u L'utilisateur mysql avec lequel vous voulez exécuter la commande
  • -p Demander votre mot de passe (vous n'avez donc pas besoin de l'enregistrer dans un fichier ni de faire apparaître la commande dans l'historique des commandes)
  • i L'intervalle en secondes.
  • Utilisez l'indicateur --verbose pour afficher la liste complète des processus et afficher la requête complète pour chaque processus. (Merci, nmat )

Il y a un inconvénient possible: les requêtes rapides risquent de ne pas s'afficher si elles sont exécutées entre les intervalles que vous avez configurés. IE: Mon intervalle est défini à une seconde et s'il existe une requête dont l'exécution est .02 secondes et qui est exécutée entre les intervalles, vous ne la verrez pas.

Utilisez cette option de préférence lorsque vous souhaitez vérifier rapidement l'exécution de requêtes sans avoir à configurer un écouteur ou quoi que ce soit d'autre.

163
halfpastfour.am

Exécutez cette requête SQL pratique pour voir exécuter les requêtes MySQL. Il peut être exécuté à partir de n’importe quel environnement, à tout moment, sans modification de code ni de frais généraux. Cela peut nécessiter une configuration d’autorisations MySQL, mais pour moi, il s’exécute sans configuration particulière.

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

Le seul problème est que vous manquez souvent des requêtes qui s'exécutent très rapidement. Il est donc particulièrement utile pour les requêtes plus longues ou lorsque le serveur MySQL enregistre des requêtes en cours de sauvegarde. D'après mon expérience, c'est exactement le moment où je souhaite afficher " "live".

Vous pouvez également ajouter des conditions pour le rendre plus spécifique pour toute requête SQL.

par exemple. Affiche toutes les requêtes en cours d'exécution pendant 5 secondes ou plus:

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

par exemple. Afficher toutes les mises à jour en cours d'exécution:

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

Pour plus de détails, voir: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html

38
python1981

Je me trouve dans une situation particulière où je ne dispose pas des autorisations nécessaires pour activer la journalisation et qui ne pourrait pas consulter les journaux s'ils étaient activés. Je ne pouvais pas ajouter de déclencheur, mais j'avais l'autorisation d'appeler show processlist. Alors, je me suis efforcé et j'ai trouvé ceci:

Créez un script bash appelé "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

Exécutez le script:

./showsqlprocesslist > showsqlprocesslist.out &

Queue la sortie:

tail -f showsqlprocesslist.out

Bingo bango. Bien que cela ne soit pas limité, cela ne prenait que 2 à 4% de CPU sur les boîtes sur lesquelles je l'avais lancé. J'espère que cela peut aider quelqu'un.

16
Michael Krauklis

C'est la configuration la plus facile sur une machine Linux Ubuntu que j'ai rencontrée. Fou de voir toutes les requêtes en direct.

Recherchez et ouvrez votre fichier de configuration MySQL, généralement /etc/mysql/my.cnf sur Ubuntu. Recherchez la section intitulée «Journalisation et réplication».

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

Décommentez simplement la variable «log» pour activer la journalisation. Redémarrez MySQL avec cette commande:

Sudo /etc/init.d/mysql restart

Nous sommes maintenant prêts à commencer à surveiller les requêtes à mesure qu’elles arrivent. Ouvrez un nouveau terminal et exécutez cette commande pour faire défiler le fichier journal, en modifiant le chemin si nécessaire.

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

Maintenant, lancez votre application. Vous verrez les requêtes de base de données commencer à voler dans la fenêtre de votre terminal. (assurez-vous que le défilement et l'historique sont activés sur le terminal)

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

15
Wil

strace

Le moyen le plus rapide de consulter les requêtes MySQL/MariaDB en direct consiste à utiliser le débogueur. Sous Linux, vous pouvez utiliser strace, par exemple:

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

Comme il y a beaucoup de caractères échappés, vous pouvez formater la sortie de strace by piping (ajoutez simplement | entre ces deux lignes) ci-dessus dans la commande suivante:

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"

Vous devriez donc voir des requêtes SQL relativement simples, sans délai, sans toucher aux fichiers de configuration.

Évidemment, cela ne remplacera pas la méthode standard d'activation des journaux décrite ci-dessous (qui implique le rechargement du serveur SQL).

dtrace

Utilisez les sondes MySQL pour afficher les requêtes MySQL en direct sans toucher le serveur. Exemple de script:

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

Enregistrez le script ci-dessus dans un fichier (comme watch.d) et exécutez:

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

En savoir plus: Prise en main de DTracing MySQL

Gibbs MySQL Spyglass

Voir cette réponse .

Les journaux

Voici les étapes utiles au développement proposé.

Ajoutez ces lignes dans votre ~/.my.cnf ou global my.cnf:

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

Chemins d'accès: /var/log/mysqld.log ou /usr/local/var/log/mysqld.log peut également fonctionner en fonction de vos autorisations sur les fichiers.

puis redémarrez votre MySQL/MariaDB par (préfixe avec Sudo si nécessaire):

killall -HUP mysqld

Ensuite, vérifiez vos journaux:

tail -f /tmp/mysqld.log

Une fois l’opération terminée, remplacez general_log par 0 (pour pouvoir l’utiliser ultérieurement), supprimez le fichier, puis redémarrez SQL Server: killall -HUP mysqld.

15
kenorb

À partir d'une ligne de commande, vous pouvez exécuter:

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

Remplacez les valeurs [x] par vos valeurs.

Ou même mieux: 

 mysqladmin -u root -p -i 1 processlist;
13
recurse

Départ mtop .

11
Chris KL

Je cherchais à faire de même et jonglais avec une solution de plusieurs publications. En outre, j'ai créé une petite application pour console qui permet de générer le texte de la requête en direct à l’écriture dans le fichier journal. Cela était important dans mon cas, car j'utilise Entity Framework avec MySQL et je dois pouvoir inspecter le code SQL généré.

Étapes pour créer le fichier journal (une duplication d’autres publications, toutes ici pour plus de simplicité):

  1. Editez le fichier situé à:

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

    Ajoutez "log = development.log" au bas du fichier. (Remarque: l'enregistrement de ce fichier m'a obligé à utiliser mon éditeur de texte en tant qu'administrateur).

  2. Utilisez MySql Workbench pour ouvrir une ligne de commande, entrez le mot de passe.

    Exécutez ce qui suit pour activer la journalisation générale qui enregistrera toutes les requêtes exécutées:

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

    Cela entraînera l'écriture des requêtes en cours d'exécution dans un fichier texte à l'emplacement suivant.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
    
  3. Créez/Exécutez une application console qui générera les informations du journal en temps réel:

    Source disponible au téléchargement ici

    La source:

    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);
            }
        }
      }
    }
    
7
gb2d

En plus des réponses précédentes décrivant comment activer la journalisation générale, je devais modifier une variable supplémentaire dans mon installation de Vanilla MySql 5.6 avant qu'un SQL ne soit écrit dans le journal:

SET GLOBAL log_output = 'FILE';

Le paramètre par défaut était "NONE".

1
David B

Gibbs MySQL Spyglass

AgilData a récemment lancé le Gibbs MySQL Scalability Advisor (outil gratuit en libre service) qui permet aux utilisateurs de capturer un flux en direct de requêtes à télécharger vers Gibbs. Spyglass (Open Source) surveillera les interactions entre vos serveurs MySQL et les applications clientes. Aucune reconfiguration ou redémarrage du serveur de base de données MySQL n'est nécessaire (client ou application).

GitHub: AgilData/gibbs-mysql-spyglass

En savoir plus: Capture de paquet MySQL avec Rust

Commande d'installation:

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