Мониторинг MySQL сервера базы данных с помощью Icinga2

Мониторинг MySQL сервера базы данных с помощью Icinga2

Roman Bogachev VMware Specialist | Drone Pilot | Traveler

Расширенный мониторинг баз данных MySQL/MariaDB с помощью бесплатной системы мониторинга Icinga2

В статье будут рассмотрены необходимые плагины мониторинга и показаны некоторые примеры конфигурации Icinga2 для мониторинга различных настроек MySQL, от отдельных серверов до master/slave с репликацией, до нескольких экземпляров MySQL на одном сервере.

Требования

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

1
firewall-cmd --add-rich-rule 'rule family="ipv4" source address="$IP_or_IP_Range" service name="mysql" accept' --permanent

Если сервер баз данных недоступен с удаленного компьютера, ознакомьтесь с документацией о том, как запустить Icinga2 в качестве агента.

Существуют различные плагины мониторинга, которые можно использовать с Icinga2 для проверки сервера MySQL. Все они являются частью стандартной установки инструментов мониторинга, поэтому можно использовать их без “изобретения велосипеда”:

  • check_mysql: простой плагин, который можно использовать для проверки подключений к серверу MySQL;
  • check_mysql_query: отправляет SQL-запросы на сервер MySQL и проверяет их результаты на разные пороговые уровни;
  • check_mysql_health: более сложный плагин для мониторинга времени безотказной работы, времени соединения, связанных потоков, попадания в поток или кеш запросов, задержки между ведущим и ведомым серверами и т. д.

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

Загрузить плагин можно по этой ссылке

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

1
GRANT USAGE ON mysql.* TO 'monitoring'@'Icinga2.local' IDENTIFIED BY 'BEST_PASSWORD';

Мониторинг single-сервер MySQL

Сперва создадим конфигурационный файл хоста, /etc/icinga2/conf.d/bogachev.biz.conf со следующим содержимым (я использую зоны, поэтому можно определить хост в zones.d/bogachev.biz.conf, как было сказано в статье про настройку хостов):

1
2
3
4
5
6
7
object Host "bogachev.biz" {
import "generic-host"
address = "IP_ADDRESS"

vars.os = "Linux"
vars.mysql = true
}

Основываясь на переменных, которые создали для хоста, теперь можем применить правила динамических сервисов.

Мониторинг доступности MySQL-сервера

Создаем конфигурационный файл /etc/icinga2/conf.d/apply_mysql.conf, (либо используем файл сервисов хоста) со следующим содержимым:

1
2
3
4
5
6
7
8
9
10
11
12
apply Service "mysql-connect" {
import "generic-service"

display_name = "MySQL Connect"
check_command = "mysql_health"

vars.mysql_health_mode = "uptime"
vars.mysql_health_username = "monitoring"
vars.mysql_health_password = "BEST_PASSWORD"

assign where host.vars.mysql == true
}

Это создаст службу с отображаемым именем MySQL Connect для всех узлов, на которых определена пользовательская переменная vars.mysql. В случае с зонами - переменная будет только на указанных хостах.

Данный пример показывает время работы сервера MySQL (vars.mysql_health_mode = «время безотказной работы»).

Вывод в Icinga2Web будет приблизительно следующий:

1
OK - database is up since 27 minutes

Мониторинг количества подключенных клиентов

По аналогии с предыдущим сервисом изменим режим работы плагина на threads-connected:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apply Service "mysql-threads-connected" {
import "generic-service"

display_name = "MySQL threads connected"
check_command = "mysql_health"

vars.mysql_health_mode = "threads-connected"
vars.mysql_health_warning = "25"
vars.mysql_health_critical = "100"
vars.mysql_health_username = "monitoring"
vars.mysql_health_password = "BEST_PASSWORD"

assign where host.vars.mysql == true
}

Вывод в Icinga2Web будет приблизительно следующий:

1
OK - 1 client connection threads

Мониторинг задержки при репликации

Если мы имеем связку серверов с репликацией, то используя плагин check_mysql_health можно контролировать задержку между серверами, особенно, если сервера разнесены по разным геолокациям.

Сперва создадим на MySQL кластере нового пользователя для мониторинга:

1
GRANT REPLICATION CLIENT ON *.* TO 'monitoring'@'%' IDENTIFIED BY 'BEST_PASSWORD';

Затем создадим новый конфигурационный файл хоста, /etc/icinga2/conf.d/replication_bogachev.biz.conf со следующим содержимым:

1
2
3
4
5
6
7
8
object Host "bogachev.biz" {
import "generic-host"
address = "IP_ADDRESS"

vars.os = "Linux"
vars.mysql = true
vars.mysql_slave = true
}

Создаем конфигурационный файл /etc/icinga2/conf.d/apply_mysql.conf, (либо используем существующий файл сервисов) со следующим содержимым:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apply Service "mysql-slave" {
import "generic-service"

display_name = "MySQL Slave Lag"
check_command = "mysql_health"

vars.mysql_health_mode = "slave-lag"
vars.mysql_health_warning = "3"
vars.mysql_health_critical = "10"
vars.mysql_health_username = "monitoring"
vars.mysql_health_password = "BEST_PASSWORD"

assign where host.vars.mysql && host.vars.mysql_slave
}

Не забудьте изменить пороговые значения на те, что подходят для вашей конфигурации. (По умолчанию Warning - 10 и Critical - 20 секунд)

Мониторинг размера базы

Плагин поддерживает отправку SQL-запросов для получения необходимой информации из базы. Ради примера рассмотрим вариант с получениям размера базы данных.

Для получения размера базы будет использовать следующий SQL-запрос:

1
SELECT SUM(data_length + index_length) / 1024 / 1024 AS 'db size' FROM information_schema.tables WHERE table_schema = 'TEST_DB';

Пример вывода:

1
2
3
4
5
+---------------+
| db size |
+---------------+
| 2857.14062500 |
+---------------+

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

Определим новый конфигурационный файл хоста, /etc/icinga2/conf.d/sql_bogachev.biz.conf со следующим содержимым:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
object Host "bogachev.biz" {
import "generic-host"

address = "bogachev.biz"

vars.os = "Linux"
vars.mysql = true

vars.database["TEST_DB"] = {
mysql_health_username = "monitoring"
mysql_health_password = "BEST_PASSWORD"
mysql_health_warning = 2048
mysql_health_critical = 8192
}
}

Создаем конфигурационный файл /etc/icinga2/conf.d/apply_mysql.conf, (либо используем существующий файл сервисов) со следующим содержимым:

1
2
3
4
5
6
7
8
9
10
11
12
13
apply Service "db_size" for (db_name => config in host.vars.database) {
import "generic-service"

display_name = "DB Size " + db_name
check_command = "mysql_health"

vars.mysql_health_mode = "sql"
vars.mysql_health_name = "SELECT SUM(data_length + index_length) / 1024 / 1024 AS 'db size' FROM information_schema.tables WHERE table_schema = '" + db_name +"';"
vars.mysql_health_name2 = "db_size"
vars.mysql_health_units = "MB"

vars += config
}

Мониторинг нескольких инстансов MySQL на одном сервере

Определим новый конфигурационный файл хоста, /etc/icinga2/conf.d/multiple_bogachev.biz.conf со следующим содержимым:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
object Host "bogachev.biz" {
import "generic-host"

address = "bogachev.biz"

vars.os = "Linux"

vars.mysql_instance["instance-1"] = {
mysql_health_port = 3306
mysql_health_username = "user1"
mysql_health_password = "BEST_PASSWORD"
}

vars.mysql_instance["instance-2"] = {
mysql_health_port = 3307
mysql_health_username = "user2"
mysql_health_password = "BEST_PASSWORD"
}

vars.mysql_instance["instance-3"] = {
mysql_health_port = 3308
mysql_health_username = "user3"
mysql_health_password = "BEST_PASSWORD"
}
}

Создаем конфигурационный файл /etc/icinga2/conf.d/apply_mysql.conf, (либо используем существующий файл сервисов) со следующим содержимым:

1
2
3
4
5
6
7
8
9
10
apply Service "mysql-multi-connect" for (mysql_instance => config in host.vars.mysql_instance) {
import "generic-service"

display_name = "MySQL Connect " + mysql_instance
check_command = "mysql_health"

vars.mysql_health_mode = "connection-time"

vars += config
}