Сообщить об ошибке.

Включаем логирование ВСЕХ и/или МЕДЛЕННЫХ запросов к БД MYSQL

Логирование ВСЕХ и/или МЕДЛЕННЫХ запросов помогает найти узкие места в работе СУБД MySQL и повысить ее производительность. Рассмотрены варианты включения как с перезагрузкой сервера, так и БЕЗ перезагрузки.

Содержание:


Логирование МЕДЛЕННЫХ запросов к БД MySQL в файл.

Включение лога длительных запросов без перезагрузки MySQL-сервера производится из терминала mysql:

mysql [(mysql)]> SET global slow_launch_time = 1;
mysql [(mysql)]> SET global slow_query_log_file = '/var/log/mysql/query_slow.log';
mysql [(mysql)]> SET global slow_query_log = 1;
mysql [(mysql)]> FLUSH LOGS;

Где установленные параметры означают следующее

  • slow_query_log = 1 - включает или выключает лог медленных запросов (1-включить; 0-выключить);
  • slow_launch_time = 1 - задает время (здесь, 1 секунда), при превышении которого запрос будет считаться медленным;
  • slow_query_log_file = ... - путь до файла, в который будут записываться все медленные запросы.
  • FLUSH LOGS - очищает log-файл.

Путь до файла логов должен указывать на директорию, в которую пользователь mysql имеет права на запись. В противном случае, при выполнении команды SET global general_log_file='...' будет появляться ошибка: Variable 'general_log_file' can't be set to the value of .... По умолчанию эти директории имеют имена: /var/log/mysql/ и '/var/lib/mysql/'. Имя файла может быть любым.

Просмотр медленных запросов в реальном времени можно осуществлять командой:

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

Через какое-то время (при накоплении запросов) можно проанализировать файл при помощи утилиты mysqldumpslow. Она покажет какой запрос сколько раз встречается в log-файле:

$ mysqldumpslow /var/log/mysql/query_slow.log

Логирование можно отключить в любое время с помощью:

mysql [(none)]> SET global slow_query_log = 0;

После перезагрузки MySQL-сервера установленный параметры примут значение по умолчанию и логирование прекратиться. Что бы включить постоянное логирование запросов, то необходимо добавить вышеуказанные параметры в файл конфигурации MySQL-сервера, в секцию [mysqld]:

[mysqld]
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log

Логирование ВСЕХ запросов в таблицу базы данных.

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

Проверим, существует ли таблица логов general_log:

mysql [(none)]> USE mysql;
mysql [(mysql)]> SHOW TABLES LIKE 'general_log';

Если не существует то создадим ее:

mysql [(mysql)]> CREATE TABLE `general_log` (
    ->    `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
    ->                           ON UPDATE CURRENT_TIMESTAMP,
    ->    `user_host` mediumtext NOT NULL,
    ->    `thread_id` bigint(21) unsigned NOT NULL,
    ->    `server_id` int(10) unsigned NOT NULL,
    ->    `command_type` varchar(64) NOT NULL,
    ->    `argument` mediumtext NOT NULL
    ->   ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log';

Включаем ведение журнала запросов в базе данных без перезагрузки MySQL-сервера:

mysql [(mysql)]> SET global log_output = 'table';
mysql [(mysql)]> SET global general_log = 1;

Логирование можно отключить в любое время командой:

mysql [(mysql)]> SET global general_log = 0;

Просмотр журнала логов:

mysql [(mysql)]> SELECT event_time, command_type, argument  FROM mysql.general_log;

После перезагрузки MySQL-сервера установленный параметры примут значение по умолчанию и логирование прекратиться. Что бы включить постоянное логирование запросов, то необходимо добавить вышеуказанные параметры в файл конфигурации MySQL-сервера, в секцию mysqld:

[mysqld]
general_log = on
global log_output = 'TABLE'

Логирование ВСЕХ запросов к БД MYSQL в файл.

С логированием ВСЕХ запросов, поступающих к БД MYSQL в файл журнала немного сложнее. Для включения логирования запросов в файл без перезапуска базы данных, необходимо выполнить следующие команды в mysql-консоли:

mysql [(none)]> SET global log_output = 'FILE';
mysql [(none)]> SET global general_log_file='/var/log/mysql/mysql_general.log';
mysql [(none)]> SET global general_log = 1;

Файл логов должен указывать на директорию, в которую учетная запись (от которой работает MySQL-сервер) имеет права на запись. В противном случае, при выполнении команды SET global general_log_file='...' будет появляться ошибка: Variable 'general_log_file' can't be set to the value of .... По умолчанию эти директории имеют имена: /var/log/mysql/ и '/var/lib/mysql/'. Имя файла может быть любым.

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

Просмотр ВСЕХ запросов, поступающих к БД в реальном времени можно осуществлять командой:

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

Логирование можно отключить в любое время с помощью:

mysql [(none)]> SET global general_log = 0;

Сложность. После включения логирования запросов в файл, необходимо настроить ротацию этого файла во избежании безконтрольного роста файла (может полностью забить файловую систему, вплоть до отказа сервера). Ротация логов настраивается в файле /etc/logrotate.d/mysql. После добавления/изменения конфигурации, необходимо применить изменения командой $ systemctl restart logrotate.service.

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

# файл с именем /etc/logrotate.d/mysql
/var/lib/mysql/*.log /var/log/mysql/*.log {
  # Если какой-либо из перечисленных выше 
  # файлов отсутствует, то не выдавать ошибок
  missingok
  #  Если файл существует, но пуст, не проводить ротацию
  notifempty
  # Проводить ротацию ежемесячно
  monthly
  # храним журналы в течение 6 месяцев
  rotate 6
  # Если файл становится слишком большим, то немедленно проводить ротацию
  maxsize 100M
  # Если размер файла слишком мал, не проводить ротацию
  minsize 10M
  # Сжимать журналы для экономии места на диске.
  compress
  # Не сжимать журнал сразу, чтобы избежать ошибок
  delaycompress
  # Не запускать скрипт `postrotate` для каждого файла, а запускать только один раз, 
  # если один или несколько файлов достигли условий ротации.
  sharedscripts
  # После каждой ротации запускать этот скрипт для очистки журналов.
  postrotate
    if test -r /etc/mysql/debian.cnf
    then
      EXTRAPARAM='--defaults-file=/etc/mysql/debian.cnf'
    fi

    if test -x /usr/bin/mariadb-admin
    then
      /usr/bin/mariadb-admin $EXTRAPARAM --local flush-error-log \
        flush-engine-log flush-general-log flush-slow-log
    fi
  endscript
}

Что бы включить логирование запросов на постоянной основе, то необходимо добавить вышеуказанные параметры в файл конфигурации MySQL-сервера, в секцию [mysqld]:

[mysqld]
general_log = on
log_output = 'FILE'
general_log_file=/var/log/mysql/mysqld_general.log

При этом необходимо будет перечитать конфигурацию MySQL-сервера командой $ systemctl restart mysql.service.