Как я могу просматривать живые запросы MySQL?

344

Как я могу отслеживать запросы MySQL на моем Linux-сервере, когда они происходят?

Например, я хотел бы настроить своего слушателя, затем запросить веб-страницу и просмотреть все запросы, которые запускал движок, или просто просмотреть все запросы, запущенные на рабочем сервере. Как я могу это сделать?

  • 0
    В зависимости от того, насколько серьезна проблема, я настоятельно рекомендую попробовать MySql Proxy. B / C он может быть размещен на сервере приложений, а) он масштабируемый, б) не должен влиять на весь трафик к БД. Это в «альфе», но уже давно. dev.mysql.com/downloads/mysql-proxy
  • 7
    Почему это было закрыто ?! Он спрашивает, как сделать X , а не для рекомендации. Почти 200 человек нашли этот вопрос полезным. Модам нужно успокоиться.
Показать ещё 2 комментария
Теги:
monitoring

11 ответов

191
Лучший ответ

Вы можете запустить команду MySQL SHOW FULL PROCESSLIST;, чтобы увидеть, какие запросы обрабатываются в любой момент времени, но, вероятно, не достигнет того, на что вы надеетесь.

Лучший способ получить историю без необходимости изменять каждое приложение с помощью сервера, вероятно, через триггеры. Вы можете настроить триггеры, чтобы каждый запрос выполнял запрос, вставляемый в какую-то таблицу истории, а затем создайте отдельную страницу для доступа к этой информации.

Помните, что это, вероятно, значительно замедлит все на сервере, добавив дополнительный INSERT поверх каждого отдельного запроса.


Изменить: другой альтернативой является Общий журнал запросов, но, записав его в плоский файл, вы удалите множество возможностей для гибкости отображения, особенно в режиме реального времени. Если вам просто нужен простой, простой в реализации способ увидеть, что происходит, включив GQL, а затем используя запуск tail -f в файле журнала, это сделает трюк.

  • 4
    Это может звучать глупо, но как именно я могу включить GQL? Я добавил log_output = file, general_log = 1 и general_log_file = / pathtofile, и добавил файл журнала, попал на сайт и ничего не получил. Что я делаю неправильно?
  • 0
    Я не могу быть уверен ни в чем, но убедитесь, что вы перезапустили сервер, а также, что выбранный вами файл - это файл, к которому у mysql будет доступ на запись.
Показать ещё 6 комментариев
378

Вы можете легко записывать каждый запрос в файл журнала:

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

Выполняйте свои запросы (на любом db). Grep или иным образом изучите /var/run/mysqld/mysqld.log

Тогда не забудьте

mysql> SET GLOBAL general_log = 'OFF';

или производительность упадет, и ваш диск будет заполняться!

  • 33
    Хороший ответ! Вы можете использовать tail -f -n300 /var/run/mysqld/mysqld.log для отслеживания вашего файла журнала
  • 4
    Обратите внимание, что для этих переменных требуется MySQL 5.1.12 или выше. Перед этим вам нужно будет перезапустить MySQL, чтобы изменить эти настройки.
Показать ещё 7 комментариев
126

Даже если ответ уже принят, я хотел бы представить, что может быть даже самым простым вариантом:

$ mysqladmin -u bob -p -i 1 processlist

Это будет печатать текущие запросы на вашем экране каждую секунду.

  • -u Пользователь mysql, который вы хотите выполнить командой
  • -p Запросить пароль (так что вам не нужно сохранять его в файле или иметь команду в истории команд)
  • i Интервал в секундах.
  • Используйте флаг --verbose, чтобы отобразить полный список процессов, отображая весь запрос для каждого процесса. (Спасибо, nmat)

Существует возможный недостаток: быстрые запросы могут не отображаться, если они работают между заданным вами интервалом. IE: мой интервал устанавливается в одну секунду, и если есть запрос, который занимает .02 секунды для запуска и пробегает между интервалами, вы его не увидите.

Используйте эту опцию предпочтительно, когда вы быстро захотите проверить выполняемые запросы, не настраивая прослушиватель или что-то еще.

  • 2
    Гораздо более простое решение, чем принятое.
  • 5
    Это лучшее решение!
Показать ещё 6 комментариев
25

Запустите этот удобный SQL-запрос, чтобы просмотреть запущенные запросы MySQL. Его можно запускать из любой среды, которая вам нравится, когда захотите, без каких-либо изменений кода или накладных расходов. Для этого может потребоваться некоторая конфигурация разрешений MySQL, но для меня она просто запускается без какой-либо специальной настройки.

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

Единственный улов в том, что вы часто пропускаете запросы, которые выполняются очень быстро, поэтому они наиболее полезны для более длинных запросов или когда сервер MySQL имеет запросы, резервные копии - по моему опыту это именно то время, когда я хочу для просмотра "живых" запросов.

Вы также можете добавить условия, чтобы сделать его более конкретным только любым SQL-запросом.

например. Показывает все запросы, выполняемые в течение 5 секунд или более:

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

например. Показать все запущенные UPDATE:

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

Подробную информацию см. в разделе http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html

15

Это самая простая настройка на машине Linux Ubuntu, с которой я столкнулся. Сумасшедший, чтобы просмотреть все запросы в прямом эфире.

Найдите и откройте файл конфигурации MySQL, обычно /etc/mysql/my.cnf на Ubuntu. Найдите раздел, в котором говорится "Регистрация и репликация"

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

Просто раскомментируйте переменную "log", чтобы включить ведение журнала. Перезапустите MySQL с помощью этой команды:

sudo /etc/init.d/mysql restart

Теперь были готовы начать мониторинг запросов по мере их поступления. Откройте новый терминал и запустите эту команду, чтобы прокрутить файл журнала, при необходимости отрегулировав путь.

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

Теперь запустите приложение. Вы увидите, что запросы базы данных начинают летать в окне терминала. (убедитесь, что у вас есть прокрутка и история включена на терминале)

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

14

У меня есть особая ситуация, когда у меня нет прав на вход в систему и у меня нет прав на просмотр журналов, если они были включены. Я не мог добавить триггер, но у меня были разрешения на вызов show processlist. Итак, я приложил все усилия и придумал следующее:

Создайте bash script, называемый "showqlprocesslist":

#!/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

Выполните команду script:

./showsqlprocesslist > showsqlprocesslist.out &

Завершить вывод:

tail -f showsqlprocesslist.out

Бинго-банго. Несмотря на то, что он не дросселировался, он занимал только 2-4% процессора на ящиках, на которых я его запускал. Надеюсь, что это поможет кому-то.

  • 0
    Ха! Вкусные. Любить это.
  • 0
    Требуется некоторая задержка, чтобы избежать слишком многословного вывода. Смотрите мой Edit, пожалуйста.
Показать ещё 2 комментария
12

Отъезд mtop.

  • 1
    Да, но удачи в установке его на Debian или Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
  • 0
    Ему удалось запустить его на Debian, но он бесполезен, поскольку пропускает множество запросов. Я вижу постоянно увеличивающийся счетчик запросов, но он редко отображает какие-либо запросы. Похоже, он отображает только те запросы, которые занимают более 1 секунды.
Показать ещё 1 комментарий
11

В командной строке вы можете запустить:

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

Замените значения [x] вашими значениями.

Или даже лучше:

 mysqladmin -u root -p -i 1 processlist;
  • 1
    На самом деле это очень хороший фрагмент кода, который может пригодиться. Спасибо!
  • 0
    именно то, что я искал !! часы нужно устанавливать отдельно.
7

strace

Самый быстрый способ увидеть живые запросы MySQL/MariaDB - использовать отладчик. В Linux вы можете использовать strace, например:

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

Поскольку существует много экранированных символов, вы можете форматировать вывод strace по трубопроводам (просто добавьте | между этими двумя одностроками) выше в следующую команду

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"

Итак, вы должны видеть довольно чистые SQL-запросы без необходимости, не касаясь файлов конфигурации.

Очевидно, это не заменит стандартный способ включения журналов, который описан ниже (что связано с перезагрузкой SQL-сервера).

dtrace

Используйте MySQL-зонды для просмотра живых MySQL-запросов, не касаясь сервера. Пример 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));
}

Сохраните выше script в файл (например, watch.d) и запустите:

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

Подробнее: Начало работы с DTracing MySQL

Ржавчина

AgilData недавно запустила советник по гибкости масштабирования Gibbs MySQL (бесплатный инструмент самообслуживания), который позволяет пользователям захватывать прямой поток запросов, которые будут загружены в Гиббс. Spyglass (Open Source) будет следить за взаимодействием между вашими MySQL-серверами и клиентскими приложениями. Никакой реконфигурации или перезагрузки сервера базы данных MySQL не требуется (клиент или приложение).

GitHub: AgilData/gibbs-mysql-spyglass

Подробнее: Пакет Capturing MySQL с Rust

Установить команду: curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash

Журналы

Здесь предлагаются шаги, полезные для разработки.

Добавьте эти строки в свой ~/.my.cnf или глобальный my.cnf:

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

Пути: /var/log/mysqld.log или /usr/local/var/log/mysqld.log также могут работать в зависимости от ваших прав доступа к файлам.

затем перезапустите MySQL/MariaDB (префикс с sudo при необходимости):

killall -HUP mysqld

Затем проверьте свои журналы:

tail -f /tmp/mysqld.log

По завершении измените general_log на 0 (чтобы вы могли использовать его в будущем), затем удалите файл и снова перезапустите SQL-сервер: killall -HUP mysqld.

  • 1
    Нет необходимости убивать сервер, если вы установили general_log из запроса MySQL. Он начнет запись в файл, на который указывает файл general_log_file .
7

Я искал сделать то же самое и собрал решение из разных сообщений, а также создал небольшое консольное приложение для вывода текста в реальном времени, когда он был записан в файл журнала. Это было важно в моем случае, поскольку я использую Entity Framework с MySQL, и мне нужно иметь возможность проверять сгенерированный SQL.

Шаги по созданию файла журнала (некоторое дублирование других сообщений, все здесь для простоты):

  • Отредактируйте файл, расположенный по адресу:

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

    Добавьте "log = development.log" в конец файла. (Примечание: для сохранения этого файла мне нужно было запустить текстовый редактор в качестве администратора).

  • Используйте утилиту MySql для открытия командной строки, введите пароль.

    Выполните следующее, чтобы включить общий журнал, который будет записывать все запрошенные запросы:

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

    Это приведет к тому, что запущенные запросы будут записаны в текстовый файл в следующем месте.

    C:\ProgramData\MySQL\MySQL Server 5.5\data\development.log
    
  • Создайте/запустите консольное приложение, которое будет выводить информацию журнала в режиме реального времени:

    Источник, который можно скачать здесь

    Источник:

    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 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);
            }
        }
      }
    }
    
  • 1
    Это выглядит действительно круто, и я определенно собираюсь взглянуть на это, замечательно принять это за проект OSS и создать инструмент профилирования!
  • 0
    Я думаю, что это хорошая идея. Я поставил репозиторий SVN на код Google. Вероятно, это самый маленький проект ОС, но пока он очень полезен. Я, вероятно, расширю это, будет интересно посмотреть, пойдет ли кто-нибудь еще дальше. code.google.com/p/livelogs
Показать ещё 1 комментарий
1

В дополнение к предыдущим ответам, описывающим, как включить общее ведение журнала, мне пришлось изменить одну дополнительную переменную в моей ванильной установке MySql 5.6, прежде чем любой SQL был записан в журнал:

SET GLOBAL log_output = 'FILE';

Значение по умолчанию: "NONE".

Ещё вопросы

Сообщество Overcoder
Наверх
Меню