Проверка версий перед миграцией
Первый важный момент, на который следует обратить внимание перед миграцией, — состояние базы данных Zabbix и наличие применённых дополнительных исправлений.
Проверить это можно в веб-интерфейсе Zabbix в разделе Информация о системе. Обратите внимание на пункт:
Database history tables upgraded: No
или в русской локализации:
Таблицы истории базы данных обновлены: Нет
В моём случае этот пункт отсутствует, что означает, что необходимые исправления уже применены и можно переходить к миграции.
Каждая версия Zabbix и используемой СУБД имеет свои особенности. Кроме того, некоторые проблемы после миграции могут проявиться не сразу, а спустя некоторое время. Поэтому возможность отката здесь особенно важна.
Проверяем версию Zabbix Server
Перед началом миграции определим установленную версию Zabbix Server:
zabbix_server -V
В моём случае:
zabbix_server (Zabbix) 7.0.6
Revision c1d7a081969 20 November 2024, compilation time: Nov 20 2024 07:51:53
Copyright (C) 2024 Zabbix SIA
License AGPLv3: GNU Affero General Public License version 3
Compiled with OpenSSL 3.0.13 30 Jan 2024
Running with OpenSSL 3.0.13 30 Jan 2024
У меня установлен Zabbix Server 7.0.6. Это важно, поскольку далее нам понадобится схема PostgreSQL именно от этой версии Zabbix.
Проверяем триггеры базы данных
Начиная с определённых версий Zabbix в базе используются триггеры, которые также необходимо учитывать при миграции.
Переходим в MySQL:
mysql
Выбираем базу Zabbix:
use zabbix;
Проверяем триггеры:
SHOW TRIGGERS\G
В моём случае вывод заканчивается следующим образом:
*************************** 65. row ***************************
Trigger: triggers_delete
Event: DELETE
Table: triggers
Statement: insert into changelog (object,objectid,operation,clock)
values (5,old.triggerid,3,unix_timestamp())
Timing: BEFORE
65 rows in set (0.01 sec)
В базе присутствует 65 триггеров. Значит, при миграции необходимо перенести не только таблицы и данные, но и правильно восстановить триггеры PostgreSQL.
Выходим из MySQL:
exit;
Устанавливаем PostgreSQL
Теперь устанавливаем PostgreSQL.
Для Ubuntu 24.04 в моём случае достаточно выполнить:
sudo apt install postgresql
После установки проверяем версию:
psql --version
В моём случае:
psql (PostgreSQL) 16.6 (Ubuntu 16.6-0ubuntu0.24.04.1)
Таким образом, на сервере установлен PostgreSQL 16.6.
Если используется Ubuntu 20.04
Если миграция выполняется на Ubuntu 20.04 и версия PostgreSQL из стандартного репозитория не подходит для используемой версии Zabbix, PostgreSQL можно установить из официального репозитория проекта.
Установка PostgreSQL на Ubuntu 20.04
Добавляем репозиторий PostgreSQL:
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
Добавляем ключ:
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
Обновляем список пакетов:
sudo apt update
Устанавливаем PostgreSQL:
sudo apt -y install postgresql
Если требуется конкретная версия, например PostgreSQL 13:
sudo apt install postgresql-13
Устанавливаем pgloader
Для переноса данных из MySQL в PostgreSQL будем использовать pgloader.
При использовании версии pgloader из стандартного репозитория Ubuntu в моём случае возникали ошибки:
FATAL error: 76 fell through ECASE expression
и:
DB-CONNECTION-ERROR:
Failed to connect to pgsql at "127.0.0.1" (port 5432)
as user "zabbix": 10 fell through ECASE expression
Поэтому в своём сценарии я собирал pgloader из исходников.
Устанавливаем зависимости
sudo apt install sbcl unzip libsqlite3-dev gawk curl make freetds-dev libzip-dev
Скачиваем pgloader
На момент выполнения миграции я использовал исходники версии 3.6.9:
wget https://github.com/dimitri/pgloader/archive/refs/tags/v3.6.9.tar.gz
Распаковываем архив:
tar xvf v3.6.9.tar.gz
Переходим в каталог:
cd pgloader-3.6.9
Компилируем pgloader
make pgloader
После завершения сборки переносим исполняемый файл:
sudo mv ./build/bin/pgloader /usr/local/bin/
Проверяем:
pgloader --version
В моём случае:
pgloader version "3.6.7~devel"
compiled with SBCL 2.2.9.debian
pgloader готов к работе.
Подготавливаем каталог для миграции
Создаём временный каталог и сразу переходим в него:
mkdir /tmp/zabbix-db-migration/ && cd $_
В нём будут находиться исходники Zabbix и подготовленные SQL-файлы.
Получаем схему PostgreSQL для Zabbix 7.0.6
Для миграции нам потребуется PostgreSQL-схема именно той версии Zabbix, которая установлена на сервере. В моём случае это Zabbix 7.0.6.
Нужную версию можно найти на странице загрузки Zabbix.
Исходники Zabbix доступны в официальном каталоге загрузок Zabbix.
Выбираем нужный релиз — в моём случае 7.0.6.
Скачиваем архив:
wget https://cdn.zabbix.com/zabbix/sources/stable/7.0/zabbix-7.0.6.tar.gz
Распаковываем:
tar -zxvf zabbix-7.0.6.tar.gz
Проверяем:
ls
zabbix-7.0.6
zabbix-7.0.6.tar.gz
Архив после распаковки можно удалить:
rm -rf zabbix-7.0.6.tar.gz
Разбираем схему Zabbix
Переходим в каталог исходников:
cd zabbix-7.0.6/
Далее в каталог PostgreSQL:
cd database/postgresql/
Проверяем содержимое:
ls
data.sql
images.sql
Makefile.am
Makefile.in
option-patches
schema.sql
timescaledb
Нас интересует файл schema.sql.
Создаём create_tables.sql
Сначала извлекаем из схемы операции создания таблиц:
grep -v 'ALTER TABLE ONLY' schema.sql | grep -v INSERT | grep -v 'CREATE INDEX' | grep -v 'CREATE UNIQUE INDEX' > /tmp/zabbix-db-migration/create_tables.sql
Возвращаемся в каталог миграции:
cd ..
cd ..
cd ..
Проверяем:
ls
create_tables.sql
zabbix-7.0.6
Удаляем триггеры из create_tables.sql
sed -i '/create\ or\ replace\ function/,$d' /tmp/zabbix-db-migration/create_tables.sql
Создаём triggers.sql
awk '/INSERT INTO dbversion/{p=1;next} /ALTER TABLE/{p=0} p' zabbix-7.0.6/database/postgresql/schema.sql > /tmp/zabbix-db-migration/triggers.sql
Создаём create_index.sql
grep -E 'CREATE INDEX|CREATE UNIQUE INDEX' zabbix-7.0.6/database/postgresql/schema.sql > /tmp/zabbix-db-migration/create_index.sql
Создаём alter_table.sql
grep 'ALTER TABLE ONLY' zabbix-7.0.6/database/postgresql/schema.sql > /tmp/zabbix-db-migration/alter_table.sql
Проверяем результат:
ls -lh /tmp/zabbix-db-migration/
В результате должны получить:
alter_table.sql
create_index.sql
create_tables.sql
triggers.sql
zabbix-7.0.6/
Таким образом, схема разделена на четыре части:
create_tables.sql— создание таблиц;triggers.sql— триггеры;create_index.sql— индексы;alter_table.sql— операции ALTER TABLE.
Подготавливаем PostgreSQL
Теперь создаём пользователя и базу данных PostgreSQL для Zabbix.
Создаём пользователя Zabbix
sudo -u postgres createuser --pwprompt zabbix
Указываем пароль пользователя.
Создаём базу данных
sudo -u postgres createdb -O zabbix zabbix
Проверяем подключение
psql --host=127.0.0.1 --dbname=zabbix --username=zabbix
После успешного подключения выходим:
\q
Временно переключаем PostgreSQL на MD5
В моём случае для работы используемой сборки pgloader потребовалось временно использовать MD5-аутентификацию.
Открываем конфигурацию PostgreSQL:
nano /etc/postgresql/16/main/postgresql.conf
Находим:
password_encryption = scram-sha-256
и временно меняем на:
password_encryption = md5
Затем открываем:
nano /etc/postgresql/16/main/pg_hba.conf
Для используемого подключения меняем метод аутентификации с:
scram-sha-256
на:
md5
Перезапускаем PostgreSQL:
systemctl restart postgresql
После изменения алгоритма необходимо заново установить пароль пользователя Zabbix:
sudo -u postgres psql -c "ALTER ROLE zabbix WITH PASSWORD 'zabbix';"
Создаём таблицы PostgreSQL
Перед переносом данных создаём структуру таблиц:
sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/create_tables.sql
После выполнения команды структура таблиц Zabbix будет создана в PostgreSQL.
Подготавливаем MySQL
Теперь необходимо подготовить исходную базу MySQL для подключения pgloader.
Открываем конфигурацию MySQL:
nano /etc/mysql/mysql.conf.d/mysqld.cnf
В моём сценарии для совместимости с pgloader использовался параметр:
default_authentication_plugin=mysql_native_password
После изменения перезапускаем MySQL:
systemctl restart mysql
Проверяем пользователя Zabbix:
mysql -e "SELECT user,host,plugin FROM mysql.user WHERE user='zabbix';"
При необходимости меняем способ аутентификации:
ALTER USER 'zabbix'@'localhost' IDENTIFIED WITH mysql_native_password BY 'zabbix';
После этого проверяем возможность подключения к базе.
Останавливаем Zabbix Server
Перед непосредственным переносом данных останавливаем Zabbix Server:
systemctl stop zabbix-server
Проверяем состояние:
systemctl status zabbix-server
На время миграции сервер мониторинга не должен записывать новые данные в исходную базу.
Создаём конфигурацию pgloader
В каталоге миграции создаём файл:
nano /tmp/zabbix-db-migration/pgloader.conf
В нём указываем подключение к исходной MySQL и целевой PostgreSQL.
LOAD DATABASE
FROM mysql://zabbix:zabbix@localhost/zabbix
INTO postgresql://zabbix:zabbix@127.0.0.1/zabbix
WITH
data only,
workers = 4,
concurrency = 1,
multiple readers per thread,
rows per range = 50000
SET
PostgreSQL PARAMETERS
maintenance_work_mem to '128MB',
work_mem to '12MB'
CAST
type datetime to timestamptz drop default drop not null using zero-dates-to-null,
type date to date drop default drop not null using zero-dates-to-null;
Пароли в строках подключения должны соответствовать вашим пользователям MySQL и PostgreSQL.
Запускаем миграцию MySQL в PostgreSQL
Запускаем pgloader:
pgloader /tmp/zabbix-db-migration/pgloader.conf
Утилита начнёт переносить данные из MySQL в заранее созданные таблицы PostgreSQL.
Во время выполнения на экране будет отображаться статистика по таблицам, количеству строк, объёму данных и времени выполнения.
В моём случае финальная часть отчёта выглядела примерно так:
--------------------------------- --------- --------- --------- --------------
COPY Threads Completion 0 4 12.781s
Reset Sequences 0 1 0.094s
Install Comments 0 0 0.000s
--------------------------------- --------- --------- --------- --------------
Total import time ✓ 942192 42.1 MB 12.87
Главное здесь — успешное завершение импорта и отсутствие фатальных ошибок переноса.
Завершаем настройку PostgreSQL
После успешного переноса данных возвращаем PostgreSQL к использованию SCRAM-SHA-256.
Возвращаем SCRAM-SHA-256
Возвращаем соответствующие параметры в:
/etc/postgresql/16/main/postgresql.conf
и:
/etc/postgresql/16/main/pg_hba.conf
После этого устанавливаем алгоритм хеширования:
sudo -u postgres psql -c "SET password_encryption='SCRAM-SHA-256';"
И заново устанавливаем пароль пользователя Zabbix:
sudo -u postgres psql -c "ALTER ROLE zabbix WITH PASSWORD 'zabbix';"
После изменения конфигурации перезапускаем PostgreSQL:
systemctl restart postgresql
Создаём индексы
sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/create_index.sql
Выполняем ALTER TABLE
sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/alter_table.sql
Создаём триггеры
sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/triggers.sql
Запускаем VACUUM
После переноса обновляем статистику PostgreSQL:
sudo -u postgres vacuumdb --dbname=zabbix --analyze --username=postgres --jobs=$(grep -c processor /proc/cpuinfo)
На этом подготовка PostgreSQL завершена.
Переключаем Zabbix Server с MySQL на PostgreSQL
Теперь необходимо заменить пакет Zabbix Server для MySQL на вариант для PostgreSQL.
Удаляем zabbix-server-mysql
sudo apt remove zabbix-server-mysql
Сохраняем конфигурацию Zabbix Server
Перед установкой нового пакета создадим резервную копию:
cp /etc/zabbix/zabbix_server.conf /etc/zabbix/zabbix_server.conf.bak
Устанавливаем Zabbix Server для PostgreSQL
apt install zabbix-server-pgsql zabbix-frontend-php php8.3-pgsql zabbix-apache-conf
Команда соответствует моему стенду с Ubuntu 24.04, Zabbix 7.0 и Apache.
Здесь устанавливаются:
zabbix-server-pgsql— Zabbix Server для PostgreSQL;zabbix-frontend-php— веб-интерфейс Zabbix;php8.3-pgsql— модуль PHP для PostgreSQL;zabbix-apache-conf— конфигурация Apache для Zabbix.
Настраиваем Zabbix Server для PostgreSQL
Открываем конфигурацию:
nano /etc/zabbix/zabbix_server.conf
Находим параметр DBPassword и указываем пароль пользователя PostgreSQL:
DBPassword=zabbix
В моём тестовом стенде использовался пароль zabbix. В своей системе укажите собственный.
Удаляем старую конфигурацию frontend
Старый файл frontend содержит параметры подключения к MySQL, поэтому удаляем его:
rm /etc/zabbix/web/zabbix.conf.php
После этого веб-интерфейс предложит заново указать параметры подключения, уже к PostgreSQL.
Перезапускаем службы
systemctl restart zabbix-server apache2
Если Zabbix Server не запускается, проверяем журнал:
nano /var/log/zabbix/zabbix_server.log
Также удобно смотреть последние сообщения командой:
tail -f /var/log/zabbix/zabbix_server.log
Настраиваем веб-интерфейс Zabbix
Теперь открываем Zabbix в браузере. В моём тестовом стенде использовался адрес:
http://zabbix7.itadminlab.ru/zabbix/
У вас адрес будет своим.
Выбираем язык
На первом экране выбираем язык интерфейса и нажимаем Далее.
Проверяем окружение
На следующем этапе Zabbix проверит установленные компоненты. Здесь должна присутствовать поддержка PostgreSQL.
Настраиваем подключение к PostgreSQL
Выбираем тип базы данных PostgreSQL.
Остальные параметры указываем в соответствии с созданной базой. В моём случае пользователь базы данных — zabbix.
Указываем пароль пользователя PostgreSQL и нажимаем Далее.
Настраиваем имя сервера и часовой пояс
В моём случае:
- имя сервера — Zabbix7;
- часовой пояс — Europe/Moscow.
Проверяем параметры
Проверяем введённые настройки:
Если всё указано правильно, нажимаем Далее.
Завершаем настройку
Нажимаем Финиш.
Входим в Zabbix
Используем тот же логин и пароль Zabbix, который использовался до миграции — данные пользователей были перенесены вместе с базой.
Проверяем панель управления
После успешного входа открываем панель управления и проверяем наличие хостов, шаблонов, элементов данных, триггеров и истории.
Если данные на месте и мониторинг продолжает работать, основная часть миграции завершена.
Проверяем работу после миграции
Я рекомендую не ограничиваться успешным входом в интерфейс. После миграции обязательно проверьте:
- поступление свежих данных от хостов;
- историю и тренды;
- работу триггеров;
- текущие проблемы;
- очередь Zabbix;
- неподдерживаемые элементы данных;
- работу Zabbix Proxy;
- уведомления и действия;
- LLD;
- графики и дашборды.
Также смотрим журнал сервера:
tail -f /var/log/zabbix/zabbix_server.log
Удаляем MySQL после миграции
После перехода на PostgreSQL старый MySQL больше не нужен.
Останавливаем MySQL
systemctl stop mysql
Удаляем пакеты MySQL
sudo apt purge mysql-server mysql-common mysql-server-core-* mysql-client-core-*
Удаляем файлы базы данных
sudo rm -Rf /var/lib/mysql/
Удаляем конфигурацию
sudo rm -Rf /etc/mysql/
Удаляем журналы
sudo rm -rf /var/log/mysql
Удаляем пользователя и группу MySQL
sudo deluser --remove-home mysql
sudo delgroup mysql
После удаления MySQL ещё раз проверяем Zabbix и убеждаемся, что сервер продолжает работать исключительно с PostgreSQL.
Часто задаваемые вопросы
Можно ли перенести базу Zabbix с MySQL на PostgreSQL?
Да. В этой инструкции для переноса данных используется pgloader, а структура PostgreSQL подготавливается на основе схемы той же версии Zabbix, которая установлена на сервере.
Нужно ли останавливать Zabbix Server перед миграцией?
Да. На этапе непосредственного переноса данных Zabbix Server лучше остановить, чтобы в исходной MySQL-базе не продолжали появляться новые данные.
Зачем схема Zabbix разбивается на несколько SQL-файлов?
В моём сценарии отдельно создаются таблицы, а после переноса данных отдельно применяются индексы, ограничения ALTER TABLE и триггеры. Для этого используются create_tables.sql, create_index.sql, alter_table.sql и triggers.sql.
Почему используется pgloader, собранный из исходников?
При миграции с версией pgloader из стандартного репозитория Ubuntu я столкнулся с ошибками ECASE. Сборка из исходников позволила выполнить миграцию на моём тестовом стенде.
Почему PostgreSQL временно переводится на MD5?
В моём сценарии это потребовалось для совместимости с используемой сборкой pgloader. После завершения переноса PostgreSQL возвращается на SCRAM-SHA-256, а пароль пользователя Zabbix создаётся заново.
Сохранятся ли хосты, шаблоны и пользователи Zabbix?
Да. Они находятся в базе данных Zabbix и переносятся из MySQL в PostgreSQL вместе с остальными данными.
Можно ли удалить MySQL сразу после миграции?
Я бы не рекомендовал этого делать на рабочей системе. Сначала убедитесь, что Zabbix стабильно работает с PostgreSQL, а резервная копия MySQL сохранена. В статье я рекомендую для боевой среды подождать месяц или два.
Можно ли использовать эту инструкцию на боевом Zabbix?
Сам алгоритм миграции рабочий, но конкретно этот сценарий я выполнял в тестовой среде. Для боевой системы необходимо учитывать объём базы, допустимое время простоя, версии Zabbix и СУБД, а также обязательно подготовить резервную копию и план отката.
Заключение
В этой статье мы выполнили миграцию базы данных Zabbix с MySQL на PostgreSQL. Проверили исходную систему, установили PostgreSQL и pgloader, подготовили схему Zabbix 7.0.6, перенесли данные, восстановили индексы и триггеры, а затем переключили Zabbix Server на PostgreSQL.
Несмотря на количество этапов, сам процесс вполне выполним, если двигаться последовательно и проверять результат после каждого шага. Особенно важно использовать схему именно своей версии Zabbix и иметь возможность откатить изменения.
Отдельно подчеркну, что описанную миграцию я выполнял в тестовой среде. В боевой инфраструктуре обязательно заранее подготовьте полноценную резервную копию, оцените время простоя и не удаляйте старую MySQL-базу сразу после перехода.
После миграции дайте Zabbix некоторое время поработать на PostgreSQL, проверьте поступление данных, триггеры, историю, уведомления, Proxy и журналы сервера. И только когда убедитесь, что всё работает штатно, можно окончательно выводить MySQL из эксплуатации.