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


493

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

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


В зависимости от того, насколько серьезна проблема, я настоятельно рекомендую попробовать 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';

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


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 секунды и выполняется между интервалами, вы не увидите его.

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


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


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.


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/


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

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

2
Spyglass, кажется, требует ключ API от сервера, который не работает, и последний коммит был 3 года назад. Не уверен, что этот продукт все еще поддерживается / работает.
— Дэн Тененбаум
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.