Миграция ZABBIX с Oracle в PostgreSQL с помощью Ora2pg
Привет, Хабр. Я являюсь действующим АБД в крупной технологической компании. Основное направление работы — это 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. Всем добра :)