Как перехватить запросы, запущенные на сервере MySQL?

14

Мы пытаемся выполнить некоторую отладку производительности сервера, и я хотел бы сделать снимок запросов, выполняемых на нашем сервере MySQL в течение пары минут.

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

Есть ли способ вывести этот запрос в файл и запускать его каждую секунду или около того?

Есть ли лучший способ перехватить все запросы?

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

hafichuk
источник
Какую ОС вы используете? Это очень легко сделать в Linux, так что я думаю, Windows?
Патрик
@Patrick Рад слышать, что это легко на Linux! Огонь прочь ...
хафичук
1
Большинство запросов будут выполняться и заканчиваться гораздо меньше, чем за секунду, и никогда не появятся в вашем списке.
Джоэл Коэль
Кроме того, более длинные запросы будут появляться много раз по одному разу для каждого цикла, но наверняка, если вы хотите, вы можете просто echo show full processlist | mysqlили лучше SELECT info FROM information_schema.processlist WHERE Command="Query" AND User!="root"использовать цикл в bash. Добавьте пару строк , и вы получите такую же функциональность запросов , чем innotopили pt-kill
теист

Ответы:

10

Я бы использовал медленный журнал запросов. Он фиксирует все запросы, а не только медленные, если вы установили long_query_time = 0.

Он также захватывает ВСЕ запросы, что не относится к упомянутым здесь методам TCP-сниффинга; те не будут захватывать запросы, выполненные через сокет. То же самое для просмотра SHOW PROCESSLIST; вы пропустите быстрые запросы.

Если вы хотите захватывать запросы через список процессов или через трафик TCP, я бы предложил использовать pt-query-digest Percona Toolkit. Он может опрашивать список процессов для вас (и иметь смысл из результатов, что очень трудно сделать, если вы сами собираете несколько примеров), и он может интерпретировать TCP-протокол MySQL, так что вы можете получить некоторые TCP трафика и проанализировать его. Конечно, это также лучший агрегатор запросов / профилировщик / репортер, когда-либо написанный, но вы не сказали, что хотите делать с запросами после их захвата.

Барон шварц
источник
13

Самый надежный способ - использовать «общий журнал запросов», который будет захватывать все запросы: http://dev.mysql.com/doc/refman/5.1/en/query-log.html.

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

Даниэль Питтман
источник
Спасибо @Daniel. Мы включили это, однако в журнале нет информации о метках времени. Есть идеи, как получить временную метку?
hafichuk
Извините, нет, ничего, кроме указания на руководство.
Даниэль Питтман
2
Медленный журнал запросов с long_query_time = 0 - лучший вариант; он по-прежнему будет захватывать все запросы.
барон Шварц
+1 для барона: общий журнал запросов не включает необходимые показатели производительности. Есть также Perl-скрипты в комплекте с MySQL сервером для анализа медленного журнала запросов (которые удаляют литеральные значения из предикатов). Но обратите внимание, что более старые версии MySQL не будут поддерживать long_query_time менее 1 секунды - если это так, а затем обновлять - в последних версиях намного больше улучшений производительности.
symcbean
5

Попробуйте эту команду как root (или используйте sudo):

tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
  if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
    if (defined $q) { print "$q\n"; }
    $q=$_;
  } else {
    $_ =~ s/^[ \t]+//; $q.=" $_";
  }
}'

Найдено http://www.mysqlperformanceblog.com/2008/11/07/poor-mans-query-logging/

Руи Педро Бернардино
источник
4

Конечно:

mysqladmin -u root -p -i 1 --verbose processlist > /tmp/pl.out

ура

HTTP500
источник
Ах ... mysqladmin. Отлично, спасибо @ HTTP500
hafichuk
1
Это фактически запускает команду processlist каждую 1 секунду. Некоторые очень быстрые запросы все еще могут избежать захвата; если нагрузка состоит из нескольких больших запросов, она будет работать, если она состоит из множества небольших запросов, это может не сработать.
LSerni
@ Isemi, ОП попросил "каждую секунду или около того".
HTTP500
4

Это может быть место для Mysql Proxy . Это в основном позволяет вам захватывать (и манипулировать) отправляемые запросы. Базовая установка для перехвата довольно проста. Затем просто измените конфигурацию клиента так, чтобы он указывал на прокси, чтобы вы могли перехватывать все запросы.

Zoredache
источник
4

Терминальная программа Wireshark tshark может помочь:

tshark -T fields -R mysql.query -e mysql.query

sudo yum install wiresharkдаст вам tshark на Amazon Linux и sudo apt-get install tsharkдаст вам tshark на Ubuntu 14+

SoMoSparky
источник
3

Я использовал решение Руи Педро Бернардино. Прекрасно работает, за исключением того, что я изменил пару вещей в первой строке, как описано ниже ...

tcpdump -i any -s 0 -l -vvv -w - dst port 3306 | strings | perl -e 'while(<>) { chomp; next if /^[^ ]+[ ]*$/;
    if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
    if (defined $q) { print "$q\n"; }
    $q=$_;
  } else {
    $_ =~ s/^[ \t]+//; $q.=" $_";
  }
}'
user1038090
источник
0

Я искал и искал, и, наконец, я приземлился в MONyog для мониторинга всех запросов в реальном времени, которые выполняются на сервере MySQL. Единственное, что следует отметить, это таблицы «Performance_schema» и «Statement_digest», и Performance_schema доступно с MySQL 5.6.14 и выше.

Mathew
источник