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

493

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

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

barfoon
источник
В зависимости от того, насколько серьезна проблема, я настоятельно рекомендую попробовать MySql Proxy. B / C он может быть размещен на сервере приложений, а) он масштабируемый, б) не должен влиять на весь трафик к БД. Это в «альфе», но уже давно. dev.mysql.com/downloads/mysql-proxy
Джефф Маасс
15
Почему это было закрыто ?! Он спрашивает, как сделать X , а не для рекомендации. Почти 200 человек нашли этот вопрос полезным. Модам нужно успокоиться.
Cerin
1
Я перефразировал этот вопрос, чтобы опустить ссылки на инструменты. Я думаю, что этот вопрос совершенно актуален здесь, так как «мы выполняем запросы, которые должны быть?» отличный первый шаг в отладке проблемы, связанной с базой данных.
Джеффри Босбоом
1
@MaasSql MySQL прокси не полезен для разработчиков php при использовании PDO, поскольку запрос и значения связываются только на сервере.
Ананда

Ответы:

300

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

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

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


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

Чад берез
источник
5
Это может звучать глупо, но как именно я могу включить GQL? Я добавил log_output = file, general_log = 1 и general_log_file = / pathtofile, и добавил файл журнала, попал на сайт и ничего не получил. Что я делаю неправильно?
Барфун
Я не могу быть уверен ни в чем, но убедитесь, что вы перезапустили сервер, а также, что выбранный вами файл - это файл, к которому у mysql будет доступ на запись.
Чад Берч
7
Я понял это - все, что мне было нужно в my.cnf, было log = / path / to / log. Затем я просто сделал хвост, и он отображает все запросы.
Барфун
1
Насколько я могу судить, нет никакого способа вызвать что-либо в операторе SELECT. Триггеры применяются только к INSERT, UPDATE, DELETE ... или я дезинформирован?
таращиться
1
Я был в том же месте ранее. В настоящее время я использую Monyog, который делает все это с минимальными накладными расходами, поэтому ничего не замедляется.
520

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

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

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

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

mysql> SET GLOBAL general_log = 'OFF';

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

artfulrobot
источник
37
Хороший ответ! Вы можете использовать tail -f -n300 /var/run/mysqld/mysqld.logдля отслеживания вашего файла журнала
Claudio Bredfeldt
4
Обратите внимание, что для этих переменных требуется MySQL 5.1.12 или выше. Перед этим вам нужно будет перезапустить MySQL, чтобы изменить эти настройки.
JLH
Есть ли способ получить параметризованные переменные, записанные в журнал? Я вижу, SELECT name FROM person where id=?но я не знаю, что idесть.
Джефф
SHOW VARIABLESне работает для меня Однако SELECT @@GLOBAL.general_log_file;работает отлично. (MariaDB 10.1.9)
фил пирожков
1
важно - вы должны проверить вывод записи с помощью SHOW VARIABLES LIKE "log_output%". Если установлено значение table, то журналы будут сохраняться в самой базе данных, а таблица - mysql.general_logне в файловой системе. Вы можете изменить его file сSET GLOBAL log_output = 'file';
Арнис Juraga
199

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

$ mysqladmin -u bob -p -i 1 processlist

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

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

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

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

halfpastfour.am
источник
11
Это лучшее решение!
user1398287
3
На мой взгляд, это лучшее решение, потому что не используйте новое соединение mysql для отправки команды каждый раз, вместо этого откройте одно соединение mysql и используйте его для отправки show processlist;
Хосе Нобиле
@JoseNobile Если в адаптере открыто соединение mysql, это не имеет значения. Мое решение не совсем подходит для OP, потому что мое решение не готово для использования в адаптере. Это, однако, быстро и легко.
halfpastfour.am
7
Вы можете добавить, --verboseчтобы увидеть полные запросы
nmat
2
Это ответ, который я искал. Это должно быть принято в качестве ответа. Это также самый простой ответ для реализации.
Чад
51

Запустите этот удобный запрос 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;

Например, Показать все запущенные ОБНОВЛЕНИЯ:

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

Для получения полной информации см .: http://dev.mysql.com/doc/refman/5.1/en/processlist-table.html

python1981
источник
17

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

Создайте bash-скрипт с именем "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

Выполните скрипт:

./showsqlprocesslist > showsqlprocesslist.out &

Хвост вывод:

tail -f showsqlprocesslist.out

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

Майкл Крауклис
источник
Ха! Очень вкусно. Любить это.
Дарт Egregious
Требуется некоторая задержка, чтобы избежать слишком многословного вывода. Смотрите мой Edit, пожалуйста.
Сликс
@Slyx спасибо за предложение поставить сон в цикл. Однако, если вы ищете недолговечные запросы, которые живут меньше времени, чем сон, вы потенциально пропустите то, что ищете. Если вы действительно просто ищете моментальный снимок, его не следует запускать в цикле. Следует также отметить, что это может потенциально пропустить очень короткие запросы.
Майкл Крауклис
17

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 в реальном времени, не касаясь сервера. Пример скрипта:

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

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

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

Узнайте больше: Начало работы с DTracing MySQL

Гиббс MySQL Spyglass

Смотрите этот ответ .

бревна

Вот шаги, полезные для разработки предложений.

Добавьте эти строки в свой ~/.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.

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

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

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

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

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

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

Wil
источник
13

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

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
На самом деле это очень хороший фрагмент, который может пригодиться. Спасибо!
MGP
именно то, что я искал !! часы нужно устанавливать отдельно.
Тило
12

Проверьте mtop .

Крис К.Л.
источник
1
Да, но удачи в установке его на Debian или Ubuntu: bugs.launchpad.net/ubuntu/+source/mtop/+bug/77980
mlissner
Ему удалось запустить его на Debian, но он бесполезен, поскольку пропускает множество запросов. Я вижу постоянно увеличивающийся счетчик запросов, но он редко отображает какие-либо запросы. Похоже, он отображает только те запросы, которые занимают более 1 секунды.
Cobra_Fast
@Cobra_Fast четко указано на странице 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 Иногда это довольно полезно.
Ян Льюис
7

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

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

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

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

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

  2. Используйте MySql Workbench, чтобы открыть командную строку, введите пароль.

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

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

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

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

    Источник доступен для скачивания здесь

    Источник:

    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
источник
1
Это выглядит действительно круто, и я определенно собираюсь взглянуть на это, замечательно принять это за проект OSS и создать инструмент профилирования!
Rippo
Я думаю, что это хорошая идея. Я поставил репозиторий SVN на код Google. Вероятно, самый маленький проект ОС, но это было очень полезно до сих пор. Я, вероятно, расширю это, будет интересно посмотреть, пойдет ли кто-нибудь еще дальше. code.google.com/p/livelogs
gb2d
OP нужен для работы на его Linux-машине. Похоже, ваш ответ предназначен для Windows-машины. Хотя этот ответ отражает творческий подход, он не может быть полезным для других.
halfpastfour.am
1

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

SET GLOBAL log_output = 'FILE';

Значением по умолчанию было «НЕТ».

Дэвид Б
источник
0

Гиббс MySQL Spyglass

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

GitHub: AgilData / gibbs-mysql-spyglass

Узнайте больше: захват пакетов MySQL с помощью Rust

Установить команду:

curl -s https://raw.githubusercontent.com/AgilData/gibbs-mysql-spyglass/master/install.sh | bash
kenorb
источник
2
Spyglass, кажется, требует ключ API от сервера, который не работает, и последний коммит был 3 года назад. Не уверен, что этот продукт все еще поддерживается / работает.
Дэн Тененбаум