Como posso visualizar consultas ao vivo do MySQL?

493

Como posso rastrear consultas MySQL no meu servidor Linux à medida que elas acontecem?

Por exemplo, eu adoraria configurar algum tipo de ouvinte, solicitar uma página da web e visualizar todas as consultas que o mecanismo executou ou apenas visualizar todas as consultas que estão sendo executadas em um servidor de produção. Como posso fazer isso?

barfoon
fonte
Dependendo de quão ruim é um problema, eu recomendo tentar o MySQL Proxy. B / c, ele pode ser colocado no servidor de aplicativos, a) é escalável, b) não precisa afetar todo o tráfego para o banco de dados. Está em 'alpha', mas já existe há muito tempo. dev.mysql.com/downloads/mysql-proxy
Jeff Maass
15
Por que isso foi fechado ?! Ele está perguntando como fazer o X , não por uma recomendação. Quase 200 pessoas acharam esta pergunta útil. Os mods precisam se acalmar.
Cerin
1
Eu reformulei esta pergunta para omitir qualquer referência a ferramentas. Eu acho que essa pergunta está perfeitamente sobre o assunto aqui, como "estamos executando as consultas que deveríamos estar?" é um ótimo primeiro passo para depurar um problema relacionado ao banco de dados.
21416 Jeffrey Bosboom
1
O proxy mysql do @MaasSql não é útil para desenvolvedores de php enquanto estiver usando o PDO, pois a consulta e os valores ficam vinculados apenas no servidor.
Ananda

Respostas:

300

Você pode executar o comando MySQL SHOW FULL PROCESSLIST;para ver quais consultas estão sendo processadas a qualquer momento, mas isso provavelmente não alcançará o que você espera.

O melhor método para obter um histórico sem precisar modificar todos os aplicativos usando o servidor é provavelmente através de gatilhos. Você pode configurar gatilhos para que cada consulta executada faça com que a consulta seja inserida em algum tipo de tabela de histórico e crie uma página separada para acessar essas informações.

Lembre-se de que isso provavelmente diminuirá consideravelmente tudo o que está no servidor, adicionando um extra INSERTa cada consulta.


Edit: outra alternativa é o General Query Log , mas tê-lo gravado em um arquivo simples removeria muitas possibilidades de flexibilidade de exibição, especialmente em tempo real. Se você quiser apenas uma maneira simples e fácil de implementar para ver o que está acontecendo, habilitar o GQL e, em seguida, usar a execução tail -fno arquivo de log faria o truque.

Chad Birch
fonte
5
Isso pode parecer bobagem, mas como exatamente posso ativar o GQL? Adicionei log_output = file, general_log = 1 e general_log_file = / pathtofile, e ajustei o arquivo de log, acesse o site e não recebi nada. O que estou fazendo errado?
20222 barfoon
Não posso ter certeza de nada, mas verifique se você reiniciou o servidor e também se o arquivo escolhido é aquele ao qual o mysql teria acesso de gravação.
Chad Birch
7
Eu descobri isso - tudo que eu precisava no my.cnf era log = / path / to / log. Então eu fiz o que aprendi e ele exibe todas as consultas.
20222 barfoon
1
Até onde eu sei, não há como disparar nada em uma instrução SELECT. Os gatilhos se aplicam apenas a INSERIR, ATUALIZAR, EXCLUIR ... ou estou mal informado?
Gabe.
1
Eu estava no mesmo lugar antes. Atualmente, estou usando o Monyog, que faz tudo isso com muito menos sobrecarga, portanto, nada fica mais lento.
520

Você pode registrar todas as consultas em um arquivo de log com muita facilidade:

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

Faça suas consultas (em qualquer banco de dados). Grep ou examinar de outra forma/var/run/mysqld/mysqld.log

Então não esqueça de

mysql> SET GLOBAL general_log = 'OFF';

ou o desempenho cairá e seu disco será preenchido!

artfulrobot
fonte
37
Boa resposta! Você pode usar tail -f -n300 /var/run/mysqld/mysqld.logpara acompanhar ao vivo do seu arquivo de log
Claudio Bredfeldt
4
Note que o MySQL 5.1.12 ou superior é necessário para essas variáveis. Antes disso, você teria que reiniciar o MySQL para alterar essas configurações.
jlh
Existe alguma maneira de obter as variáveis ​​parametrizadas gravadas no log? Estou vendo, SELECT name FROM person where id=?mas não sei o que idé.
Jeff Jeff
SHOW VARIABLESnão funcionou para mim. No entanto, SELECT @@GLOBAL.general_log_file;funciona bem. (MariaDB 10.1.9)
phil pirozhkov
1
important - Você deve verificar a saída do log com SHOW VARIABLES LIKE "log_output%". Se estiver definido como table, os logs serão salvos no próprio banco de dados, a tabela mysql.general_lognão está no sistema de arquivos. Você pode alterá-lo para file comSET GLOBAL log_output = 'file';
Arnis Juraga
199

Mesmo que uma resposta já tenha sido aceita, eu gostaria de apresentar qual poderia ser a opção mais simples:

$ mysqladmin -u bob -p -i 1 processlist

Isso imprimirá as consultas atuais na tela a cada segundo.

  • -u O usuário do mysql que você deseja executar o comando como
  • -p Solicite sua senha (para que você não precise salvá-la em um arquivo ou para que o comando apareça no seu histórico de comandos)
  • i O intervalo em segundos.
  • Use o --verbosesinalizador para mostrar a lista completa de processos, exibindo a consulta inteira para cada processo. (Obrigado, nmat )

Existe uma possível desvantagem: as consultas rápidas podem não aparecer se forem executadas entre o intervalo que você configurou. IE: Meu intervalo é definido em um segundo e, se houver uma consulta que demora .02alguns segundos para ser executada e é executada entre intervalos, você não a verá.

Use essa opção de preferência quando desejar verificar rapidamente a execução de consultas sem precisar configurar um ouvinte ou qualquer outra coisa.

halfpastfour.am
fonte
11
Essa é a melhor solução!
user1398287
3
Na minha opinião, esta solução melhor, porque não use uma nova conexão mysql para enviar o comando a cada vez; em vez disso, abra uma conexão mysql e use-a para enviar a show processlist;
Jose Nobile
@JoseNobile Se você mantiver a conexão mysql aberta no seu adaptador, isso realmente não importa. Minha solução não é exatamente correta para OP, porque minha solução não está pronta para uso em um adaptador. É, no entanto, rápido e fácil.
Halfpastfour.am
7
Você pode adicionar --verbosepara ver as consultas completas
NMAT
2
Esta é a resposta que eu estava procurando. Deve ser aceito como resposta. É também a resposta mais fácil de implementar.
Chad
51

Execute esta consulta SQL conveniente para ver as consultas MySQL em execução. Pode ser executado a partir de qualquer ambiente que você quiser, sempre que quiser, sem nenhuma alteração ou sobrecarga de código. Pode exigir alguma configuração de permissões do MySQL, mas, para mim, é executado sem nenhuma configuração especial.

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

O único problema é que muitas vezes você perde as consultas que são executadas muito rapidamente, por isso é mais útil para consultas de execução mais longa ou quando o servidor MySQL tem consultas que estão fazendo backup - na minha experiência, esse é exatamente o momento em que desejo visualizar " consultas ao vivo ".

Você também pode adicionar condições para torná-lo mais específico a qualquer consulta SQL.

Por exemplo, mostra todas as consultas em execução por 5 segundos ou mais:

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

por exemplo, Mostrar todas as atualizações em execução:

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

Para obter detalhes completos, consulte: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html

python1981
fonte
17

Estou em uma situação específica em que não tenho permissões para ativar o logon e não teria permissões para ver os logs se eles estivessem ativados. Não foi possível adicionar um gatilho, mas eu tinha permissões para chamar show processlist. Então, esforcei-me ao máximo e cheguei a isso:

Crie um script bash chamado "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

Execute o script:

./showsqlprocesslist > showsqlprocesslist.out &

Cauda da saída:

tail -f showsqlprocesslist.out

Bingo Bango. Mesmo que não seja acelerado, ele consumiu apenas 2-4% da CPU nas caixas em que o executei. Espero que talvez isso ajude alguém.

Michael Krauklis
fonte
Ha! Delicioso. Adoro.
Darth Egregious
Ele precisa de algum atraso para evitar muita saída detalhada. Veja meu Edit, por favor.
Slyx 21/05
@Slyx obrigado pela sugestão de adormecer. No entanto, se você estiver procurando por consultas de curta duração que durem menos tempo que o sono, provavelmente perderá o que está procurando. Se você está realmente procurando um instantâneo a tempo, isso não deve ser executado em um loop. Também deve ser observado que isso ainda pode potencialmente perder consultas de vida muito curta.
Michael Krauklis
17

strace

A maneira mais rápida de ver consultas ao vivo do MySQL / MariaDB é usar o depurador. No Linux, você pode usar strace, por exemplo:

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

Uma vez que existem muitos caracteres de escape, você pode formatar a saída do strace pela tubulação (basta adicionar |entre estes dois one-liners) acima para o seguinte comando:

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"

Portanto, você deve ver consultas SQL bastante limpas sem tempo, sem tocar nos arquivos de configuração.

Obviamente, isso não substituirá a maneira padrão de ativar logs, descrita abaixo (que envolve recarregar o servidor SQL).

dtrace

Use os testes do MySQL para visualizar as consultas ao vivo do MySQL sem tocar no servidor. Script de exemplo:

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

Salve o script acima em um arquivo (como watch.d) e execute:

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

Saiba mais: Introdução ao MySQL DTracing

Gibbs MySQL Spyglass

Veja esta resposta .

Histórico

Aqui estão as etapas úteis para propostas de desenvolvimento.

Adicione estas linhas ao seu ~/.my.cnfou global my.cnf:

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

Caminhos: /var/log/mysqld.logou /usr/local/var/log/mysqld.logtambém podem funcionar dependendo das suas permissões de arquivo.

então reinicie seu MySQL / MariaDB (prefixo com sudose necessário):

killall -HUP mysqld

Em seguida, verifique seus logs:

tail -f /tmp/mysqld.log

Depois de terminar, a mudança general_logpara 0(assim você pode usá-lo no futuro), em seguida, remover o arquivo e reiniciar o servidor SQL novamente: killall -HUP mysqld.

kenorb
fonte
1
Não é necessário matar o servidor se você definir a general_logpartir de uma consulta MySQL. Ele começará a gravar no arquivo que general_log_fileestá apontando.
Robert Brisita 8/11
15

Esta é a configuração mais fácil em uma máquina Linux Ubuntu que eu já encontrei. É louco ver todas as consultas ao vivo.

Encontre e abra seu arquivo de configuração do MySQL, geralmente /etc/mysql/my.cnf no Ubuntu. Procure a seção que diz “Log e replicação”

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

Apenas descomente a variável "log" para ativar o log. Reinicie o MySQL com este comando:

sudo /etc/init.d/mysql restart

Agora estamos prontos para começar a monitorar as consultas à medida que elas entram. Abra um novo terminal e execute este comando para rolar o arquivo de log, ajustando o caminho, se necessário.

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

Agora execute seu aplicativo. Você verá as consultas ao banco de dados começarem a aparecer na janela do seu terminal. (verifique se a rolagem e o histórico estão ativados no terminal)

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

Wil
fonte
13

Em uma linha de comando, você pode executar:

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

Substitua os valores [x] pelos seus valores.

Ou melhor ainda:

 mysqladmin -u root -p -i 1 processlist;
recurso
fonte
1
Este é realmente um trecho muito bom que pode ser útil .. Obrigado!
MGP 01/02
Exatamente o que eu estava procurando!! O relógio precisa ser instalado separadamente.
Tilo
12

Confira mtop .

Chris KL
fonte
1
Sim, mas boa sorte instalá-lo no Debian ou Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner
Conseguiu executá-lo no debian, mas é meio inútil, pois falta muitas consultas. Eu posso ver o contador de consultas subindo constantemente, mas ele raramente exibe consultas. Parece que ele exibe apenas as consultas que demoram mais de aproximadamente 1 segundo.
precisa saber é o seguinte
@Cobra_Fast claramente indicado na página 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 Às vezes é bastante útil.
Ian Lewis
7

Eu estava procurando fazer o mesmo, e reuni uma solução de várias postagens, além de criar um pequeno aplicativo de console para gerar o texto da consulta ao vivo, conforme ele é gravado no arquivo de log. Isso foi importante no meu caso, pois estou usando o Entity Framework com MySQL e preciso poder inspecionar o SQL gerado.

Etapas para criar o arquivo de log (alguma duplicação de outras postagens, todas aqui por simplicidade):

  1. Edite o arquivo localizado em:

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

    Adicione "log = development.log" ao final do arquivo. (Observe que salvar este arquivo exigiu que eu executasse meu editor de texto como administrador).

  2. Use o MySql Workbench para abrir uma linha de comando, digite a senha.

    Execute o seguinte para ativar o log geral que registrará todas as consultas executadas:

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

    Isso fará com que as consultas em execução sejam gravadas em um arquivo de texto no seguinte local.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
  3. Crie / execute um aplicativo de console que produza as informações de log em tempo real:

    Fonte disponível para download aqui

    Fonte:

    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
fonte
1
Isso parece bem legal e eu definitivamente vou dar uma olhada nisso, seria ótimo aceitar isso como um projeto OSS e criar uma ferramenta de criação de perfil!
Rippo
Eu acho que é uma boa ideia. Eu coloquei um repositório SVN no código do Google. Provavelmente o menor projeto de SO de todos os tempos, mas isso tem sido muito útil até agora. Provavelmente vou estendê-lo, estar interessado em ver se mais alguém vai além. code.google.com/p/livelogs
gb2d 22/02
O OP precisa que ele funcione em sua máquina Linux. Parece que sua resposta é para uma máquina Windows. Embora essa resposta reflita a criatividade, ela pode não ser útil para outras pessoas.
Halfpastfour.am
1

Além das respostas anteriores que descrevem como habilitar o log geral, tive que modificar uma variável adicional na minha instalação do MySql 5.6 vanilla antes de qualquer SQL ser gravado no log:

SET GLOBAL log_output = 'FILE';

A configuração padrão era 'NENHUM'.

David B
fonte
0

Gibbs MySQL Spyglass

A AgilData lançou recentemente o Gibbs MySQL Scalability Advisor (uma ferramenta gratuita de autoatendimento) que permite aos usuários capturar uma transmissão ao vivo de consultas a serem carregadas na Gibbs. O Spyglass (que é de código aberto) observará as interações entre os servidores MySQL e os aplicativos clientes. Nenhuma reconfiguração ou reinicialização do servidor de banco de dados MySQL é necessária (cliente ou aplicativo).

GitHub: AgilData / gibbs-mysql-spyglass

Saiba mais: Pacote de captura de MySQL com Rust

Comando de instalação:

curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash
kenorb
fonte
2
O Spyglass parece exigir uma chave de API de um servidor inoperante, e a última confirmação foi há 3 anos. Não tenho certeza se este produto ainda é compatível / está funcionando.
Dan Tenenbaum