Кейс
Zabbix не переносит историю между СУБД. Перевезли 4.2 → 7.0 с MySQL на PostgreSQL — без потерь и без простоя
Перенесли Zabbix 4.2 с MySQL на Zabbix 7.0/PostgreSQL, сохранив более полумиллиарда строк истории. Двухфазная миграция, сверка 203 таблиц и переключение без остановки мониторинга.
Схема читается сверху вниз. Первый проход поднимает версию схемы на прежней СУБД, второй переливает данные в целевую. Разделение на два прохода оставляет каждый шаг обратимым.
01Подъём версии схемы на прежней СУБД
Структура приведена к целевой версии, данные остались на месте
02Переливка данных в целевую СУБД
Переключение: запись в DNS и остановка служб на прежнем сервере
Сервер мониторинга у клиента — регионального оператора связи — жил на CentOS 6 с Zabbix 4.2 и MySQL. Обе системы давно вне поддержки: ни обновлений безопасности, ни современных возможностей. На нём висело 167 узлов и около 67 000 метрик — коммутаторы, маршрутизаторы, гипервизоры — и история наблюдений за несколько лет, которую нельзя терять: по ней смотрят тренды, разбирают инциденты, планируют ёмкость.
Задача звучала просто — «переехать на актуальный Zabbix». Сложной её делали три условия, которые действовали одновременно.
Почему это не «поставить новый и переключиться»
Условие первое: смена СУБД. Мы переезжали с MySQL на PostgreSQL — на нём у нас уже отлажено сжатие истории через TimescaleDB. Но Zabbix переносит данные только между одинаковыми движками. Между MySQL и PostgreSQL штатного пути нет: структуры таблиц, типы, кодировки различаются, а «просто выгрузить и залить» ломается на первой же несовместимости.
Условие второе: вся история. Можно было развернуть чистый Zabbix 7.0 и начать собирать с нуля — но тогда пропадают годы трендов. Клиент прямо просил перенести историю целиком.
Условие третье: без простоя. Мониторинг — это то, что замечает аварии. Оставить сеть оператора без наблюдения на время переезда — недопустимо. Значит, старый сервер должен работать до последней секунды, а переключение — быть мгновенным.
Каждое условие по отдельности решается легко. Вместе они и составляют инженерную задачу.
Двухфазный переезд: сначала версия, потом движок
Прямого моста MySQL → PostgreSQL нет, поэтому разложили переход на два независимых шага, каждый из которых Zabbix делать умеет.
Фаза 1 — поднять версию схемы, не меняя движок. На новой машине развернули временный MySQL 8 и восстановили в него дамп старой базы. Затем один раз прогнали против него Zabbix 7.0 — сервер сам провёл миграцию схемы с 4.2 до 7.0 (длинная цепочка изменений таблиц, накопленных за пять мажорных версий). На выходе — та же история, но уже в структуре Zabbix 7.0.
Фаза 2 — перенести данные в PostgreSQL с идентичной схемой. На боевой машине подняли чистый Zabbix 7.0 на PostgreSQL. Теперь схемы по обе стороны одинаковые (обе — 7.0), и задача сузилась до переливки данных таблица-в-таблицу. Лили потоком напрямую, без промежуточных файлов, выравнивая колонки по порядку и отключив проверки внешних ключей на время загрузки.
Дьявол, как обычно, в деталях кодировок и типов: тут — невидимые управляющие символы в текстовых полях, там — бинарные данные (иконки), которые нельзя гнать через текстовый поток. Каждый такой случай — отдельная аккуратная обработка, а не «одна волшебная команда».
Полмиллиарда строк — и сверка один в один
Основной объём переезда — это история. Две самые тяжёлые таблицы содержали 251 и 261 миллион строк; всего в базе — 203 таблицы. После переливки сверили количество строк по каждой таблице между источником и приёмником: 203 из 203 совпали точно, расхождений — ноль. Отдельно долили бинарную таблицу иконок, которую текстовый поток не тянет, — через безопасное кодирование.
Сверка построчного счётчика — не формальность. Именно она отличает «вроде переехало» от «переехало полностью»: без неё молча потерянная таблица всплыла бы через месяцы, когда кто-то откроет старый график и не увидит данных.
TimescaleDB: история как гиперитаблицы
Дальше историю по метрикам (history, trends) перевели в гиперитаблицы
TimescaleDB — это разбивает большие таблицы на порции по времени и позволяет Zabbix
сжимать старые данные. У оператора связи история — это десятки гигабайт; сжатие
кратно уменьшает занимаемое место и ускоряет запросы к свежим данным.
Конвертацию делали по одной таблице за раз (каждая — отдельной транзакцией с видимым прогрессом), а не одной гигантской операцией на полмиллиарда строк: так процесс управляем, а сбой на одной таблице не откатывает остальные.
Ноль простоя: параллельная работа и бесшовный катовер
Ключ к «без простоя» — не в скорости переливки, а в том, что новый сервер работал параллельно со старым. Пока шла миграция и проверки, старый Zabbix продолжал собирать данные и слать оповещения — сеть ни на секунду не оставалась без наблюдения.
Когда клиент подтвердил, что в новом интерфейсе всё на месте — данные, графики, история за прошлые месяцы, — переключение свелось к двум действиям:
- Запись DNS: привычный адрес сервера превратили в псевдоним (CNAME) на новую машину — закладки и ссылки операторов повели на новый Zabbix, ничего не меняя на их стороне.
- Остановка служб Zabbix на старом сервере (с отключением автозапуска), чтобы два сервера не дублировали работу.
Старую виртуальную машину при этом не удаляли — оставили выключенной как точку мгновенного отката. Операторы перехода не заметили: тот же адрес, те же данные, только интерфейс новее и история на месте.
Результат
- Zabbix 4.2 на CentOS 6 → Zabbix 7.0 LTS на Debian 13 с PostgreSQL и TimescaleDB. Актуальная, поддерживаемая система вместо снятой с поддержки.
- Вся история перенесена — 203 из 203 таблиц, свыше полумиллиарда строк, сверка один-в-один. Ни одного потерянного графика.
- Ноль простоя мониторинга. Старый сервер собирал данные до момента переключения, катовер — мгновенный.
- Вся операция заняла шесть дней (30 июля — 4 августа): от разворачивания новой машины до переключения, при непрерывно работающем мониторинге.
Что стоит забрать из этого кейса
- Смена СУБД в Zabbix — это две задачи, а не одна. Штатного моста между движками нет, но переход раскладывается на «поднять версию» и «перелить в одинаковую схему» — и каждый шаг уже поддерживается. Обходной путь честнее лобового «экспорт-импорт», который ломается на несовместимостях.
- История переносится целиком или не переносится. Полмиллиарда строк — это годы трендов, ради которых мониторинг и держат. Построчная сверка после переливки — то, что отделяет полный перенос от «кажется, всё».
- Простой мониторинга не обязателен. Новый сервер поднимается и наполняется параллельно со старым; переключение — это запись DNS и остановка старых служб, а не многочасовое окно. Старую машину оставляют выключенной как мгновенный откат.
- Обновляться дешевле планово, чем аварийно. Система вне поддержки — это не «пока работает». Плановый переезд занимает несколько дней и проходит незаметно; вынужденный, после инцидента на EOL-платформе, стоит дороже и по деньгам, и по нервам.
Переезд получился незаметным для тех, кто пользуется мониторингом каждый день, — и это и есть правильный результат такой операции. Не «мы всё героически перенесли за одну ночь», а «вы работали как обычно, а под капотом сменились и версия, и база данных, и операционная система — со всей историей и без единой минуты слепой зоны».