Як я можу переглянути живі запити MySQL?


493

Як я можу відслідковувати запити MySQL на моєму сервері Linux, як вони трапляються?

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


Залежно від того, наскільки погана проблема, я б дуже рекомендував спробувати MySql Proxy. B / c він може бути розміщений на сервері додатків, а) він масштабований, б) не повинен впливати на весь трафік на db. Це в "альфі", але існує вже давно. dev.mysql.com/downloads/mysql-proxy
Джефф Маас

15
Чому це було закрито ?! Це питання, як зробити X , а не для рекомендації. Майже 200 людей вважають це питання корисним. Модникам потрібно заспокоїтися.
Серін

1
Я переформулював це питання, щоб пропустити будь-які посилання на інструменти. Я вважаю, що це питання є ідеально актуальним тут, оскільки "чи виконуємо ми запити?" це чудовий перший крок налагодження проблеми, пов’язаної з базою даних.
Джефрі Босбум

1
@MaasSql mysql проксі не корисний для розробників php при використанні PDO, оскільки запит і значення прив'язуються лише на сервері.
Ананда

Відповіді:


299

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

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

Майте на увазі, що це, ймовірно, значно сповільнить усе на сервері, але додаючи додаткові INSERTзверху до кожного запиту.


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


5
Це може здатися дурним, але як саме я можу включити GQL? Я додав log_output = файл, 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';

Виконайте свої запити (на будь-якому db). Греп або іншим чином досліджуйте/var/run/mysqld/mysqld.log

Тоді не забувайте

mysql> SET GLOBAL general_log = 'OFF';

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


37
Хороша відповідь! Ви можете використовувати tail -f -n300 /var/run/mysqld/mysqld.logдля того, щоб відслідковувати свій файл журналу
Клаудіо Бредфельтт

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)
phil pirozhkov

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
ЦЕ найкраще рішення!
користувач1398287

3
На мій погляд, це краще рішення, оскільки не використовуйте нове з'єднання mysql для надсилання команди щоразу, замість цього відкрийте одне з'єднання mysql і використовуйте це для надсилання списку показів процесів;
Хосе Нобіле

@JoseNobile Якщо ви підтримуєте з'єднання mysql відкритим у своєму адаптері, це насправді не має значення. Моє рішення не зовсім підходить для ОП, оскільки моє рішення не готове до використання в адаптері. Однак це швидко і просто.
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/uk/processlist-table.html


17

Я перебуваю в особливій ситуації, коли у мене немає дозволів на ввімкнення входу, і я б не мав дозволу бачити журнали, якщо вони були ввімкнені. Я не зміг додати тригер, але у мене були дозволи на виклик показу списку процесів. Отже, я доклав максимум зусиль і придумав це:

Створіть 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

Bingo bango. Незважаючи на те, що він не заглушений, він займав лише 2-4% процесора на коробках, на яких я його запускав. Сподіваюся, можливо, це комусь допоможе.


Га! Смачний. Любіть це.
Дарт Егрегійний

Потрібна певна затримка, щоб уникнути занадто багатослівного виводу. Дивіться мою редагування будь-ласка
Slyx

@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, як правило, /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

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

ВІД 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, але його kindof марний, оскільки він пропускає безліч запитів. Я бачу, що лічильник запитів постійно піднімається, але він рідко відображає запити. Схоже, він відображає лише запити, які займають більше 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 для відкриття командного рядка, введення пароля.

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

    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 та створити інструмент для профілювання!
Ріппо

Я думаю, що це гарна ідея. Я поставив SVN-репо на код google. Напевно, найменший проект ОС коли-небудь, але це було дуже корисно до цих пір. Я, мабуть, продовжую це, зацікавимося, щоб хтось більше взяв його далі. code.google.com/p/livelogs
gb2d

ОП потрібно, щоб він працював на своїй машині Linux. Схоже, ваша відповідь призначена для машини Windows. Хоча ця відповідь відображає творчість, вона може не бути корисною для інших.
halfpastfour.am

1

На додаток до попередніх відповідей, що описують, як увімкнути загальний журнал, мені довелося змінити одну додаткову змінну в моїй ванільній MySql 5.6 установці, перш ніж будь-який SQL був записаний у журнал:

SET GLOBAL log_output = 'FILE';

За замовчуванням було встановлено "NONE".


0

Гіббс MySQL Spyglass

Нещодавно AgilData запустила Gibbs MySQL Advisor Scalability Advisor (безкоштовний інструмент самообслуговування), який дозволяє користувачам фіксувати прямий потік запитів для завантаження в Gibbs. Spyglass (який є відкритим кодом) буде спостерігати за взаємодією між вашими MySQL серверами та клієнтськими програмами. Ніяка переконфігурація або перезапуск сервера баз даних 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.