Миграция ZABBIX с Oracle в PostgreSQL с помощью Ora2pg

2504197b5d57e39a539ee4dece87fa43

Привет, Хабр. Я являюсь действующим АБД в крупной технологической компании. Основное направление работы — это Oracle, PostgreSQL и различные кластерные решения на основе СУБД PostgreSQL. Думаю многим будет полезен опыт миграции БД ZABBIX с Oracle в PostgreSQL, т.к. сам задавшись данным вопросом, не нашел конкретных шагов реализации данной задачи, а пришлось многие моменты реализовывать самому.

Исходные данные: Zabbix 6.0.26, OL8, single instance Oracle 19.12, размер БД — 3 TB.

Конечный результат: Zabbix 6.0.26, OL8, ванильный СУБД PostgreSQL 14.10, смигрированная БД со всеми данными (допускалось отсутствие детализированной информации за время перелива основной пачки данных таблиц history, history_log, history_str, history_text, history_uint, trends, trends_uint).

Проверяем успешность установки.

foreach(@modules){
my $ver= $inst->version($_) || "???";
printf("%-12s -- %s\n",$_,$ver);
}

createuser --pwprompt zabbix
createdb -O zabbix zabbix
psql
alter user zabbix Superuser;

Создание таблиц и индексов (Скрипт поставляется c ПО zabbix, обычно в директории /usr/share/doc/zabbix-server-pgsql/).

psql -d zabbix -U zabbix < /opt/pgsql/14/execute_ddl/table.sql

Обращаю внимание, что создавать надо только таблицы и индексы.

Удаление ограничений NOT NULL.

psql -d zabbix -U zabbix < /opt/pgsql/14/execute_ddl/drop_not_null.sql

Пример:

/triggers:
ALTER TABLE triggers ALTER COLUMN url DROP NOT NULL;
ALTER TABLE triggers ALTER COLUMN comments DROP NOT NULL;
ALTER TABLE triggers ALTER COLUMN error DROP NOT NULL;
ALTER TABLE triggers ALTER COLUMN recovery_expression DROP NOT NULL;
ALTER TABLE triggers ALTER COLUMN correlation_tag DROP NOT NULL;
ALTER TABLE triggers ALTER COLUMN opdata DROP NOT NULL;
ALTER TABLE triggers ALTER COLUMN event_name DROP NOT NULL;
ALTER TABLE triggers ALTER COLUMN uuid DROP NOT NULL;

Если не удалить, перенос данных утилитой ora2pg будет фейлится из-за включенного not null.

Список таблиц для которых необходимо удалять ограничения скинул ниже.

Запуск переноса исторических данных.

cd /home/oracle/test_project
/usr/local/bin/ora2pg -t COPY -o data.sql -b ./data -c ./config/ora2pg.conf -j 45 -a 'TABLE[history,history_log,history_str,history_text,history_uint,trends,trends_uint]'

Может занять несколько дней, в зависимости от объёма данных.

Установка и настройка timescaledb.

yum install timescaledb-tsl_14-2.8.1-1.rhel8.x86_64

psql -d zabbix
alter system set shared_preload_libraries = 'timescaledb';
:wq
systemctl restart postgresql-14.service

Обращаю внимание, чтобы была доступна функция сжатия данных, необходимо устанавливать пакет timescaledb-tsl.

psql -d zabbix
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
ALTER DATABASE "zabbix" SET timescaledb.telemetry_level = 'basic';
cd /opt/pgsql/14/execute_ddl/
psql -d zabbix -U zabbix < /opt/pgsql/14/execute_ddl/timescaledb.sql

Если есть необходимость пересоздать timescaledb, то делаем
drop extension timescaledb CASCADE;

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

cd /home/oracle/test_project
/usr/local/bin/ora2pg -t COPY -o data.sql -b ./data -c ./config/ora2pg.conf -P 90 -j 90 -J 90 -a 'TABLE[acknowledges, actions, alerts, auditlog, autoreg_host, conditions,config,config_autoreg_tls,dashboard,dashboard_page,dashboard_user,dashboard_usrgrp,dchecks,drules,event_recovery,event_tag,events,expressions,functions,globalmacro,globalvars,graph_discovery,graph_theme,graphs,graphs_items,group_discovery,group_prototype,ha_node,host_discovery,host_inventory,host_tag,hostmacro,hosts,hosts_groups,hosts_templates,housekeeper,hstgrp,ids,images,interface,interface_discovery,interface_snmp,item_condition,item_discovery,item_preproc,item_rtdata,item_tag,items,lld_macro_path,maintenances,maintenances_groups,maintenances_hosts,maintenances_windows,media,media_type,media_type_message,media_type_param,opcommand,opcommand_hst,operations,opgroup,opmessage,opmessage_grp,opmessage_usr,optemplate,problem,problem_tag,profiles,regexps,rights,role,role_rule,scripts,sessions,sla,sysmap_shape,sysmaps,sysmaps_elements,sysmaps_link_triggers,sysmaps_links,timeperiods,token,trigger_depends,trigger_discovery,trigger_tag,triggers,users,users_groups,usrgrp,valuemap,valuemap_mapping,widget,widget_field]'

После переноса оперативных данных включаем обратно not null в таблицах.

psql -d zabbix -U zabbix < /opt/pgsql/14/execute_ddl/add_not_null.sql

Пример включения:

update history_str set value='' where value is null;
alter table history_str alter column value set not null;

Обязательно надо включать для всех таблиц, у которых удаляли not null, в противном случае zabbix_server будет падать при запуске.

Список таблиц для которых необходимо добавить ограничения скинул ниже.

Накатывание ограничений и внешних ключей.

psql -d zabbix -U zabbix < /opt/pgsql/14/execute_ddl/constraint_fk.sql

(Скрипт поставляется c ПО zabbix, обычно в директории /usr/share/doc/zabbix-server-pgsql/).

Создание триггеров в целевой БД.

psql -d zabbix

create or replace function hosts_name_upper_upper()
returns trigger language plpgsql as $func$
begin
update hosts set name_upper=upper(name)
where hostid=new.hostid;
return null;
end $func$;
create trigger hosts_name_upper_insert after insert
on hosts
for each row execute function hosts_name_upper_upper();
create trigger hosts_name_upper_update after update
of name on hosts
for each row execute function hosts_name_upper_upper();
create or replace function items_name_upper_upper()
returns trigger language plpgsql as $func$
begin
update items set name_upper=upper(name)
where itemid=new.itemid;
return null;
end $func$;
create trigger items_name_upper_insert after insert
on items
for each row execute function items_name_upper_upper();
create trigger items_name_upper_update after update
of name on items
for each row execute function items_name_upper_upper();

DDL этих триггеров можно посмотреть в источнике Oracle.

Запуск zabbix_server. Мониторинг работы.

Включение сжатия.

UPDATE config SET db_extension=’timescaledb’;UPDATE config SET compression_status=1,compress_older=’180d’;

select db_extension, hk_history_global, hk_trends_global, compression_status, compress_older from config;

Перезагружаем сервис СУБД PostgresQL.

Если не включать сжатие, то объём генерируемых данных будет ~ в 8 раз больше, чем с включенным.

Список таблиц для которых необходимо сначала удалить, а потом добавить ограничения NOT NULL:

acknowledges, actions, alerts, autoreg_host, conditions, dashboard, dashboard_page, dchecks, globalmacro, auditlog, config, config_autoreg_tls, event_tag, graphs, group_prototype, ha_node, history_str, hostmacro, host_discovery, hosts, host_inventory, hstgrp, interface, interface_snmp, item_condition, item_discovery, item_preproc, item_rtdata, items, item_tag, maintenances, media_type, media_type_message, media_type_param, valuemap, opmessage, role_rule, problem_tag, profiles, scripts, sysmap_shape, sysmaps, sysmaps_elements, sysmaps_links, token, triggers, trigger_tag, users, widget, widget_field, history_log, history_str, history_text

Настройки утилиты ora2pg (количество потоков, DATA_LIMIT и т.д.) опытным путем необходимо настраивать под конкретную развёрнутую инфраструктуру.

Здесь я описал только порядок действий который успешно позволит перенести данные БД ZABBIX на СУБД PostgreSQL.

Надеюсь данная статья окажется полезной, для тех кто планирует перевести систему мониторинга с Oracle на PostgreSQL. Всем добра :)

© Habrahabr.ru