- PVSM.RU - https://www.pvsm.ru -
В свете того, что Zabbix с некоторых пор поддерживает TimescaleDB, а тут еще и вышел новый LTS релиз Zabbix, то наверняка многие заинтересовались, как осуществить миграцию с MySQL на PostgreSQL.
Несмотря на текст на картинке, вполне можно просто так взять и мигрировать Zabbix с MySQL на PostgreSQL. В интернете есть немало рецептов такой миграции, например:
Доклад с Zabbix Meetup [1]
Видео с Youtube канала Dmitry Lambert [2]
Но я не нашел ни в одном из таких докладов информации, как же минимизировать downtime вашего мониторинга в случае, если полная миграция занимает несколько часов, что конечно зачастую является неприемлемым.
Ниже я опишу свое решение данной проблемы и те подводные камни, которые пришлось обходить по пути.
Важно упомянуть, что я до сих использую Zabbix 4.0. Возможно, в новых версиях схема БД поменялась и поэтапная миграция, описанная ниже, там невозможна.
Как известно, основной объем базы данных Zabbix сервера занимают исторические данные: таблицы истории и трендов (далее для краткости я буду называть эти данные историей). При этом сам Zabbix сервер способен без проблем запуститься и без этих данных. Сразу же возникает мысль: а что если при миграции для начала проигнорировать историю, запустить мониторинг, а уже затем разобраться с историей?
Я не буду по ходу статьи описывать все команды, например, как установить PostgreSQL. Думаю, в этой статье оно ни к чему, да и каждый сам может с этим справиться.
Установим нужное ПО:
Необходимо настроить PostgreSQL сервер и операционную систему, на которой он установлен.
Я также не буду подробно останавливаться на этой теме, так как пост не о тюнинге производительности, скажу лишь:
Также нужно до начала миграции настроить мониторинг PostgreSQL.
Так как я еще не переехал с версии Zabbix 4.0, то новеньким официальным шаблоном воспользоваться не могу, но мне отлично подошел вот этот:
https://github.com/lesovsky/zabbix-extensions/tree/master/files/postgresql [6]
Кроме этого, непосредственно перед началом миграции лучше отключить все способы оповещения в Zabbix, чтобы не потревожить людей сработавшими триггерами nodata, т.к. при первом после миграции запуске исторических данных в базе у нас не будет.
Ну и обязательно делайте резервные копии и проверяйте весь процесс на тестовом окружении. Собственно, все приключения я получил именно на нем.
Последний момент подготовки перед миграцией — останавливаем Zabbix server:
systemctl stop zabbix-server
Для начала, как и в любом другом мануале по миграции Zabbix, разделим файл schema.sql, расположенный в директории database/postgresql исходников zabbix, на 2 части:
в одной у нас будут CREATE, в другой ALTER.
На выходе имеем 2 файла: create.sql, alter.sql
Применим файл create.sql к нашей БД:
cat create.sql | psql -Uzabbix zabbix
Подготовим файл для pgloader — zabbix.load.config
LOAD DATABASE
FROM mysql://zabbix:zabbix-password@localhost/zabbix
INTO postgresql://zabbix:zabbix-password@192.168.1.1:5432/zabbix
WITH include no drop,
truncate,
create no tables,
create no indexes,
no foreign keys,
reset sequences,
data only
SET MySQL PARAMETERS
max_execution_time = '0'
SET PostgreSQL PARAMETERS
maintenance_work_mem TO '1024MB', work_mem to '128MB'
EXCLUDING TABLE NAMES MATCHING ~/history.*/, ~/trend.*/
ALTER SCHEMA 'zabbix' RENAME TO 'public';
Обратите внимание на строку
EXCLUDING TABLE NAMES MATCHING ~/history.*/, ~/trend.*/
с ее помощью мы пропускаем таблицы истории
Запустим миграцию:
pgloader zabbix.load.config
Ждем буквально минуту, проверяем, что ошибок при миграции нет (символ галки во втором столбце):
Применим файл alter.sql к нашей БД:
cat alter.sql | psql -Uzabbix zabbix
Полагаю, важно, что в файле alter.sql нет никаких упоминаний таблиц trend и history. По крайней мере в версии 4.0 именно так обстоят дела. Наверное, при ином раскладе были бы проблемы, т.к. в существующих в сети мануалах по миграции данные сначала загружаются в БД, а потом применяется alter.sql
Удалим пакеты Zabbix, связанные с MySQL и заменим их теми, что нужны для PostgreSQL. На этот раз я приведу примеры для CentOS 7, чтобы было понятно, какие пакеты нам нужны:
yum remove zabbix-server-mysql zabbix-web-mysql
yum install zabbix-server-pgsql zabbix-web-pgsql php-pgsql
А лучше смотрите официальную документацию по установке для вашей ОС:
https://www.zabbix.com/documentation/4.0/manual/installation/install_from_packages [7]
Сбросим настройки Web интерфейса Zabbix, чтобы заново пройти его настройку:
rm /etc/zabbix/web/zabbix.conf.php
Укажем часовой пояс в файле:
/etc/httpd/conf.d/zabbix.conf
Настроим новый zabbix_server.conf: укажем нужные значения в директивах DBHost, DBPort, DBUser, DBName, DBPassword.
Настала пора запустить наш Zabbix Server!
systemctl start zabbix-server
Идем по адресу web-интерфейса zabbix (http(s)://ip/zabbix), проходим по шагам мастера.
После настройки web-интерфейса вы увидите, что все ваши узлы, шаблоны, группы и т.п. будут на месте. Не будет только исторических данных. Вы можете в этом убедиться, посмотрев любые графики за прошлые периоды — там пусто.
Теперь можно проследить, что данные от ваших проверок начали поступать на сервер, что ошибок в логах нет, что ложные срабатывания триггеров отсутствуют. Как только вы поняли, что ситуация под контролем, можете включить оповещения, отключенные на этапе подготовки.
Можно немного выдохнуть — мониторинг опять заработал.
Теперь надо просто запустить миграцию истории, но чтобы этот процесс не сильно нагружал СУБД.
Так думал я, но все оказалось интереснее.
Перед вторым шагом миграции я решил создать в моем тестовом окружении нагрузку на Zabbix сервер. В тестовом окружении отсутствовали Zabbix прокси (это логично, так как мои основные прокси с тестовым сервером работать не намерены), так что нагрузку я решил создавать на самом сервере. Для этого с помощью API я создал около 200 хостов и попросил Zabbix сервер совершать проверки icmp и web checks к этим хостам каждую секунду. Получил около 1000 NVPS.
Очереди не росли, Zabbix server и PostgreSQL легко справлялись с такой нагрузкой.
Пора мигрировать историю.
Подготовим файл zabbix.load.data для pgloader:
LOAD DATABASE
FROM mysql://zabbix:zabbix-password@localhost/zabbix
INTO postgresql://zabbix:zabbix-password@192.168.1.1:5432/zabbix
WITH include no drop,
no truncate,
create no tables,
create no indexes,
no foreign keys,
reset sequences,
data only,
prefetch rows = 5000,
multiple readers per thread
SET MySQL PARAMETERS
max_execution_time = '0',
net_read_timeout = ‘86400’,
net_write_timeout = ‘86400’
SET PostgreSQL PARAMETERS
maintenance_work_mem TO '1024MB', work_mem to '128MB'
INCLUDING ONLY TABLE NAMES MATCHING ~/history.*/, ~/trend.*/
ALTER SCHEMA 'zabbix' RENAME TO 'public';
Обратите внимание на строки:
no truncate
говорит о том, что при начале миграции не будут очищены все мигрируемые таблицы. Ведь в истории уже появляются данные, так как мониторинг запущен.
INCLUDING ONLY TABLE NAMES MATCHING ~/history.*/, ~/trend.*/
говорит о том, что мигрировать в этот раз будут только таблицы истории.
Запускаем миграцию
pgloader zabbix.load.data
Миграция истории началась, процесс этот может быть долгим. В моем случае при размере базы около 150 Гб и не самом сильном железе миграция истории занимает 4-5 часов.
Поначалу все шло хорошо. Потом я обнаружил, что загрузка CPU на PostgreSQL сервере растет линейно, и со временем ресурсов для нормальной работы уже не хватало (на графике load average на 1 ядро):
В логи Zabbix сервера сплошным полотном начали сыпаться медленные запросы SELECT. Как я понял, для того, чтобы совершить web check, нужно для начала сделать SELECT.
Я попробовал снизить интенсивность миграции. Для этого изменил следующие параметры в файле zabbix.load.data:
prefetch_rows = 1000,
workers = 1,
concurrency = 1,
single reader per thread
Но с такими настройками не поменялось ничего, кроме скорости миграции. Нагрузка росла также линейно со временем.
Ну не зря же я обвесил PostgreSQL мониторингом. Изучаю его показатели и вижу, что линейный рост нагрузки явно совпадал с продолжительностью транзакции, которую создал pgloader:
А также с количеством tuples, которые возвращала PostgreSQL клиентам в ответ на их запросы:
Идем в интернет, ищем информацию о том, как ведет себя PostgreSQL при длинных транзакциях. И находим вот такой замечательный доклад с конференции HighLoad:
https://www.youtube.com/watch?v=3h48iowNbwo [8]
Советую посмотреть доклад, но если вкратце, то при наличии длинной транзакции в PostgreSQL не срабатывает механизм внутристраничной очистки (single-page cleanup). И это приводит к росту тех самых возвращаемых tuple. СУБД приходится разбираться, какой tuple ей нужен, что ведет к росту загрузки CPU.
Я проверил мою ситуацию — действительно, достаточно открыть транзакцию, создать в ней таблицу, а затем НЕ закрыть транзакцию:
begin;
create table x(n numeric);
У спустя некоторое время видим рост загрузки CPU:
Падение загрузки в конце графика — это закрытая вручную транзакция.
Видимо, с этой особенностью придется мириться. Что можно сделать? Например, мигрировать историю отдельно, тренды отдельно, чтобы хоть немного уменьшить продолжительность транзакции.
Но это не всё. У меня все таки получилось сделать так, чтобы эта особенность PostgreSQL не мешала.
Немного о моей реальной инсталляции Zabbix. На ней почти все задачи сбора данных делегированы на Zabbix прокси. Сервер занимается лишь приемом данных и всякими триггерами/препроцессингом. Но как я написал выше, на тестовой инсталляции все проверки исполнял сам сервер.
Я вынес все задачи сбора данных на прокси в тестовой инсталляции, сильно снизив нагрузку на Zabbix Server и PostgreSQL. И оказалось, что это помогло! После этого никакая длинная транзакция не создавала сверхвысокой нагрузки на CPU, не мешала мониторингу нормально работать. Ну либо по какой-то причине внутристраничная очистка PostgreSQL при таком сценарии заработала. Может быть знатоки PostgreSQL подскажут?
Как оказалось, произвести миграцию Zabbix с MySQL на PostgreSQL с минимизацией downtime лишь немного сложнее стандартной миграции. Делайте тестовую инсталяцию, экспериментируйте, и все получится.
Спасибо всем, кто дочитал пост до конца. Надеюсь, он кому-то поможет спланировать и оттестировать миграцию.
Ну и конечно жду feedback, может быть более опытные коллеги укажут на недочеты.
Автор: Никита Лепехин
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/mysql/355576
Ссылки в тексте:
[1] Доклад с Zabbix Meetup: https://assets.zabbix.com/files/events/meetup_ru_20200619/MySQL2PgSQL_Alexander_Petrov_Gavrilov.pdf
[2] Видео с Youtube канала Dmitry Lambert: https://www.youtube.com/watch?v=S-C5NCZJnt0
[3] https://habr.com/ru/post/505108/: https://habr.com/ru/post/505108/
[4] https://pgtune.leopard.in.ua/: https://pgtune.leopard.in.ua/
[5] https://postgrespro.ru/docs/postgrespro/12/index.html: https://postgrespro.ru/docs/postgrespro/12/index.html
[6] https://github.com/lesovsky/zabbix-extensions/tree/master/files/postgresql: https://github.com/lesovsky/zabbix-extensions/tree/master/files/postgresql
[7] https://www.zabbix.com/documentation/4.0/manual/installation/install_from_packages: https://www.zabbix.com/documentation/4.0/manual/installation/install_from_packages
[8] https://www.youtube.com/watch?v=3h48iowNbwo: https://www.youtube.com/watch?v=3h48iowNbwo
[9] Источник: https://habr.com/ru/post/513470/?utm_source=habrahabr&utm_medium=rss&utm_campaign=513470
Нажмите здесь для печати.