¿Cómo puedo ver consultas MySQL en vivo?

493

¿Cómo puedo rastrear consultas MySQL en mi servidor Linux a medida que ocurren?

Por ejemplo, me encantaría configurar algún tipo de escucha, luego solicitar una página web y ver todas las consultas que ejecutó el motor, o simplemente ver todas las consultas que se ejecutan en un servidor de producción. ¿Cómo puedo hacer esto?

barfoon
fuente
Dependiendo de qué tan grave sea un problema, recomendaría probar MySql Proxy. B / c se puede colocar en el servidor de aplicaciones, a) es escalable, b) no tiene que afectar todo el tráfico a la base de datos. Está en 'alfa', pero ha existido por mucho tiempo. dev.mysql.com/downloads/mysql-proxy
Jeff Maass
15
¿Por qué se cerró esto? Se está preguntando cómo hacer X , no como una recomendación. Casi 200 personas encontraron útil esta pregunta. Los mods necesitan calmarse.
Cerin
1
He reformulado esta pregunta para omitir cualquier referencia a las herramientas. Creo que esta pregunta es perfectamente sobre el tema aquí, como "¿estamos ejecutando las consultas que deberíamos estar?" es un excelente primer paso para depurar un problema relacionado con la base de datos.
Jeffrey Bosboom
1
@MaasSql mysql proxy no es útil para los desarrolladores de php mientras usan PDO ya que la consulta y los valores se vinculan solo en el servidor.
Ananda

Respuestas:

300

Puedes ejecutar el comando MySQL SHOW FULL PROCESSLIST; para ver qué consultas se están procesando en un momento dado, pero eso probablemente no logrará lo que espera.

El mejor método para obtener un historial sin tener que modificar todas las aplicaciones que utilizan el servidor es probablemente a través de disparadores. Puede configurar desencadenantes para que cada consulta ejecute resultados en la consulta que se inserta en algún tipo de tabla de historial, y luego cree una página separada para acceder a esta información.

Tenga en cuenta que esto probablemente ralentizará considerablemente todo en el servidor, con la adición de un extra INSERTen cada consulta.


Editar: otra alternativa es el Registro de consultas generales , pero tenerlo escrito en un archivo plano eliminaría muchas posibilidades de flexibilidad de visualización, especialmente en tiempo real. Sin embargo, si solo desea una forma simple y fácil de implementar para ver lo que está sucediendo, habilitar el GQL y luego usar la ejecución tail -fen el archivo de registro sería el truco.

Abedul Chad
fuente
55
Esto puede sonar tonto, pero ¿cómo puedo habilitar GQL exactamente? Agregué log_output = file, general_log = 1 y general_log_file = / pathtofile, y seguí el archivo de registro, llegué al sitio y no obtuve nada. ¿Qué estoy haciendo mal?
barfoon
No puedo estar seguro de nada, pero asegúrese de reiniciar el servidor y también de que el archivo que eligió sea uno al que mysql tendría acceso de escritura.
Chad Birch
77
Lo descubrí: todo lo que necesitaba en my.cnf era log = / path / to / log. Luego acabo de hacer la cola y muestra todas las consultas.
barfoon
1
Por lo que puedo decir, no hay forma de activar nada en una instrucción SELECT. Los disparadores solo se aplican a INSERTAR, ACTUALIZAR, ELIMINAR ... ¿o estoy mal informado?
Gabe.
1
Estuve en el mismo lugar antes. Actualmente, estoy usando Monyog que hace todo esto con muy poca sobrecarga, por lo tanto, nada se ralentiza.
520

Puede registrar cada consulta en un archivo de registro con mucha facilidad:

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

Haga sus consultas (en cualquier base de datos). Grep o examinar de otra manera/var/run/mysqld/mysqld.log

Entonces no olvides

mysql> SET GLOBAL general_log = 'OFF';

¡o el rendimiento caerá en picado y su disco se llenará!

artfulrobot
fuente
37
¡Buena respuesta! Puede utilizar tail -f -n300 /var/run/mysqld/mysqld.logpara realizar un seguimiento en vivo de su archivo de registro
Claudio Bredfeldt
44
Tenga en cuenta que se requiere MySQL 5.1.12 o superior para estas variables. Antes de eso, tendría que reiniciar MySQL para cambiar esta configuración.
jlh
¿Hay alguna forma de escribir las variables parametrizadas en el registro? Estoy viendo SELECT name FROM person where id=?pero no sé qué ides.
Jeff
SHOW VARIABLESno funciono para mi Sin embargo SELECT @@GLOBAL.general_log_file;funciona bien. (MariaDB 10.1.9)
phil pirozhkov
1
importante : debe verificar la salida de registro con SHOW VARIABLES LIKE "log_output%". Si se establece en table, los registros se guardarán en la base de datos en sí, la tabla mysql.general_logno en el sistema de archivos. Puede cambiarlo a file conSET GLOBAL log_output = 'file';
Arnis Juraga
199

Aunque ya se ha aceptado una respuesta, me gustaría presentar lo que podría ser la opción más simple:

$ mysqladmin -u bob -p -i 1 processlist

Esto imprimirá las consultas actuales en su pantalla cada segundo.

  • -u El usuario mysql al que desea ejecutar el comando como
  • -p Solicite su contraseña (para que no tenga que guardarla en un archivo o que el comando aparezca en su historial de comandos)
  • i El intervalo en segundos.
  • Use la --verbosebandera para mostrar la lista completa de procesos, mostrando la consulta completa para cada proceso. (Gracias, nmat )

Existe un posible inconveniente: las consultas rápidas pueden no aparecer si se ejecutan entre el intervalo que configuró. IE: Mi intervalo se establece en un segundo y si hay una consulta que tarda unos .02segundos en ejecutarse y se ejecuta entre intervalos, no la verá.

Utilice esta opción preferentemente cuando desee comprobar rápidamente la ejecución de consultas sin tener que configurar un oyente ni nada más.

halfpastfour.am
fuente
11
¡Esta es la mejor solución!
user1398287
3
En mi opinión, esta solución es mejor porque no use una nueva conexión mysql para enviar el comando cada vez, en su lugar abra una conexión mysql y úsela para enviar la lista de procesos show;
Jose Nobile
@JoseNobile Si mantiene abierta la conexión mysql en su adaptador, realmente no importa. Mi solución no es exactamente la adecuada para OP porque mi solución no está lista para usarse en un adaptador. Sin embargo, es rápido y fácil.
halfpastfour.am
77
Puede agregar --verbosepara ver las consultas completas
nmat
2
Esta es la respuesta que estaba buscando. Debe ser aceptado como la respuesta. También es la respuesta más fácil de implementar.
Chad
51

Ejecute esta conveniente consulta SQL para ver cómo se ejecutan consultas MySQL. Se puede ejecutar desde cualquier entorno que desee, cuando lo desee, sin ningún cambio de código o gastos generales. Puede requerir alguna configuración de permisos de MySQL, pero para mí simplemente se ejecuta sin ninguna configuración especial.

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

El único inconveniente es que a menudo se pierden consultas que se ejecutan muy rápidamente, por lo que es más útil para consultas de ejecución más larga o cuando el servidor MySQL tiene consultas que se están respaldando; en mi experiencia, este es exactamente el momento en que quiero ver " en vivo "consultas.

También puede agregar condiciones para hacerlo más específico en cualquier consulta SQL.

Por ejemplo, muestra todas las consultas que se ejecutan durante 5 segundos o más:

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

Por ejemplo, Mostrar todas las ACTUALIZACIONES en ejecución:

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

Para más detalles, consulte: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html

python1981
fuente
17

Estoy en una situación particular en la que no tengo permisos para activar el inicio de sesión y no tendría permisos para ver los registros si estuvieran activados. No pude agregar un disparador, pero tenía permisos para llamar a show processlist. Entonces, hice un gran esfuerzo y se me ocurrió esto:

Cree un script bash llamado "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

Ejecute el script:

./showsqlprocesslist > showsqlprocesslist.out &

Cola la salida:

tail -f showsqlprocesslist.out

Bingo bango. A pesar de que no está estrangulado, solo tomó 2-4% de CPU en las cajas en las que lo ejecuté. Espero que esto ayude a alguien.

Michael Krauklis
fuente
¡Decir ah! Delicioso. Quiéralo.
Darth Egregious
Necesita un poco de retraso para evitar una producción demasiado detallada. Ver mi edición por favor.
Slyx
@Slyx gracias por la sugerencia de poner un sueño en el circuito. Sin embargo, si está buscando consultas de corta duración que vivan menos tiempo que el sueño, posiblemente perderá lo que está buscando. Si realmente está buscando una instantánea a tiempo, esto no debería ejecutarse en un bucle. También se debe tener en cuenta que esto aún podría perder consultas de muy corta duración.
Michael Krauklis
17

strace

La forma más rápida de ver consultas MySQL / MariaDB en vivo es usar el depurador. En Linux puedes usar strace, por ejemplo:

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

Puesto que hay gran cantidad de caracteres de escape, es posible formato de salida de strace por tuberías (sólo tiene que añadir |entre estos dos de una sola línea) anterior en el siguiente orden:

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"

Por lo tanto, debería ver consultas SQL bastante limpias sin tiempo, sin tocar los archivos de configuración.

Obviamente, esto no reemplazará la forma estándar de habilitar registros, que se describe a continuación (que implica volver a cargar el servidor SQL).

dtrace

Use las sondas MySQL para ver las consultas MySQL en vivo sin tocar el servidor. Script de ejemplo:

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

Guarde el script anterior en un archivo (como watch.d) y ejecute:

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

Obtenga más información: Introducción a DTracing MySQL

Catalejo MySQL de Gibbs

Mira esta respuesta .

Registros

Estos son los pasos útiles para el desarrollo que propone.

Agregue estas líneas en su ~/.my.cnfo global my.cnf:

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

Rutas: /var/log/mysqld.logo /usr/local/var/log/mysqld.logtambién puede funcionar dependiendo de los permisos de su archivo.

luego reinicie su MySQL / MariaDB por (prefijo con sudosi es necesario):

killall -HUP mysqld

Luego revise sus registros:

tail -f /tmp/mysqld.log

Después de terminar, cambiar general_loga 0(para que pueda utilizarlo en el futuro), a continuación, quitar el archivo y el servidor SQL reinicio de nuevo: killall -HUP mysqld.

kenorb
fuente
1
No es necesario matar el servidor si configura general_logdesde una consulta MySQL. Comenzará a escribir en el archivo al que general_log_fileapunta.
Robert Brisita
15

Esta es la configuración más fácil en una máquina Linux Ubuntu que he encontrado. Loco por ver todas las consultas en vivo.

Encuentre y abra su archivo de configuración MySQL, generalmente /etc/mysql/my.cnf en Ubuntu. Busque la sección que dice "Registro y replicación"

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

Simplemente elimine el comentario de la variable "log" para activar el registro. Reinicie MySQL con este comando:

sudo /etc/init.d/mysql restart

Ahora estamos listos para comenzar a monitorear las consultas a medida que entran. Abra una nueva terminal y ejecute este comando para desplazar el archivo de registro, ajustando la ruta si es necesario.

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

Ahora ejecuta tu aplicación. Verá que las consultas de la base de datos comienzan a volar en la ventana de su terminal. (asegúrese de tener el desplazamiento y el historial habilitados en la terminal)

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

Wil
fuente
13

Desde una línea de comando puedes ejecutar:

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

Reemplace los valores [x] con sus valores.

O mejor:

 mysqladmin -u root -p -i 1 processlist;
recurse
fuente
1
Este es realmente un muy buen fragmento que puede ser útil. ¡Gracias!
Pop
¡¡Exactamente lo que estaba buscando!! El reloj debe instalarse por separado.
Tilo
12

Echa un vistazo a mtop .

Chris KL
fuente
1
Sí, pero buena suerte al instalarlo en Debian o Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner
Se las arregló para que se ejecute en Debian, pero no tiene ningún valor, ya que pierde muchas consultas. Puedo ver que el contador de consultas sube constantemente, pero rara vez muestra consultas. Parece que solo muestra las consultas que tardan más de aproximadamente 1 segundo.
Cobra_Fast
@Cobra_Fast claramente indicado en la página de 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 A veces es bastante útil.
Ian Lewis
7

He estado buscando hacer lo mismo, y he creado una solución de varias publicaciones, además de haber creado una pequeña aplicación de consola para generar el texto de la consulta en vivo tal como está escrito en el archivo de registro. Esto fue importante en mi caso, ya que estoy usando Entity Framework con MySQL y necesito poder inspeccionar el SQL generado.

Pasos para crear el archivo de registro (alguna duplicación de otras publicaciones, todo aquí por simplicidad):

  1. Edite el archivo ubicado en:

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

    Agregue "log = development.log" al final del archivo. (Tenga en cuenta que guardar este archivo requirió que ejecutara mi editor de texto como administrador).

  2. Use MySql workbench para abrir una línea de comando, ingrese la contraseña.

    Ejecute lo siguiente para activar el registro general que registrará todas las consultas ejecutadas:

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

    Esto hará que las consultas en ejecución se escriban en un archivo de texto en la siguiente ubicación.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
  3. Cree / ejecute una aplicación de consola que generará la información de registro en tiempo real:

    Fuente disponible para descargar aquí

    Fuente:

    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);
            }
        }
      }
    }
gb2d
fuente
1
Esto se ve realmente genial y definitivamente voy a echarle un vistazo, ¡será genial tomar esto como un proyecto OSS y crear una herramienta de creación de perfiles!
Rippo
Creo que es una buena idea. He puesto un repositorio SVN en el código de google. Probablemente el proyecto de sistema operativo más pequeño de la historia, pero hasta ahora ha sido muy útil. Probablemente lo extienda, esté interesado en ver si alguien más lo lleva más lejos. code.google.com/p/livelogs
gb2d
OP lo necesita para funcionar en su máquina Linux. Parece que su respuesta está destinada a una máquina con Windows. Aunque esta respuesta refleja creatividad, puede no ser útil para otros.
halfpastfour.am
1

Además de las respuestas anteriores que describen cómo habilitar el registro general, tuve que modificar una variable adicional en mi instalación Vanilla MySql 5.6 antes de escribir cualquier SQL en el registro:

SET GLOBAL log_output = 'FILE';

La configuración predeterminada era 'NINGUNO'.

David B
fuente
0

Catalejo MySQL de Gibbs

AgilData lanzó recientemente el Asesor de escalabilidad MySQL de Gibbs (una herramienta de autoservicio gratuita) que permite a los usuarios capturar una transmisión en vivo de consultas para cargarlas en Gibbs. Spyglass (que es de código abierto) observará las interacciones entre sus servidores MySQL y las aplicaciones cliente. No se necesita reconfigurar o reiniciar el servidor de base de datos MySQL (cliente o aplicación).

GitHub: AgilData / gibbs-mysql-spyglass

Más información: captura de paquetes MySQL con Rust

Instalar comando:

curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash
kenorb
fuente
2
Spyglass parece requerir una clave API de un servidor que está inactivo, y la última confirmación fue hace 3 años. No estoy seguro de que este producto todavía sea compatible / funcione.
Dan Tenenbaum,