Привет, Хабр. Я являюсь действующим АБД в крупной технологической компании. Основное направление работы - это 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).
Инструмент миграции данных - Ora2pg.
- Устанавливаем пакеты на целевой сервер СУБД PostgreSQL. 
 - yum install oracle-instantclient19.14-basic-19.14.0.0.0-1.x86_64.rpm
 yum install oracle-instantclient19.14-devel-19.14.0.0.0-1.x86_64.rpm
 yum install oracle-instantclient19.14-jdbc-19.14.0.0.0-1.x86_64.rpm
 yum install oracle-instantclient19.14-sqlplus-19.14.0.0.0-1.x86_64.rpm
- 
Настраиваем instant client. 
 cd /usr/lib/oracle/19.14/client64/lib/network/admin/
 ll
 vi /usr/lib/oracle/19.14/client64/lib/network/admin/tnsnames.oraZABBIX =
 (DESCRIPTION =
 (ADDRESS_LIST =
 (ADDRESS = (PROTOCOL = TCP)(HOST = zabbix.localhost)(PORT = 1521))
 )
 (CONNECT_DATA =
 (SERVICE_NAME = zabbix)
 )
 )zabbix.localhost - указываем ip адрес источника сервера с СУБД Oracle БД ZABBIX 
- 
Под root устанавливаем переменные среды: vi ~/.bashrcexport PATH=/usr/lib/oracle/19.14/client64/bin:$PATHexport LD_LIBRARY_PATH=/usr/lib/oracle/19.14/client64/lib:$LD_LIBRARY_PATH
 :wq
- Подключаемся и проверяем клиента. 
 - sqlplus /nolog
 conn Username/Password@ZABBIX
- Устанавливаем DBI для подключения к Oracle. 
 - tar -zxvf DBI-1.643.tar.gz
 cd ./DBI-1.643/
 perl Makefile.PL
 make
 make install
- 
Устанавливаем DBD для подключения к Oracle. 
 tar xzf DBD-Oracle-1.74.tar.gz
 cd DBD-Oracle-1.74
 export ORACLE_HOME=/usr/lib/oracle/19.14/client64/libexport LD_LIBRARY_PATH=/usr/lib/oracle/19.14/client64/lib:$LD_LIBRARY_PATH
 export TNS_ADMIN=$ORACLE_HOME/network/admin
 perl Makefile.PL
 make
 make install
Проверяем успешность установки.
              vi check.pl
        #!/usr/bin/perl
        use strict;
        use ExtUtils::Installed;
        my $inst=ExtUtils::Installed->new();
        my @modules = $inst->modules();
        foreach(@modules){
          my $ver= $inst->version($_) || "???";
         printf("%-12s -- %s\n",$_,$ver);
         }
        chmod +x check.pl
        ./check.pl
- 
Установка СУБД PostgreSQL (Пропущу данный пункт, т.к. информации по инициализации кластера СУБД достаточно в интернете). В моем случае PostgreSQL устанавливал там же где и Ora2pg. 
- 
Устанавливаем DBD и дополнительные библиотеки для PostgreSQL. yum install postgresql-plperl
 yum install postgresql-devel
 yum install perl-DBD-Pg
 yum install perl
- 
Приступаем к сборке утилиты ora2pg. tar xzf ora2pg-23.1.tar.gz
 cd ora2pg-23.1
 perl Makefile.PL
 make && make install
- 
Создаем пользователя oracle. useradd oracle
 groupadd oinstall
 usermod -a -G oinstall oracle
- 
Инициализируем проект ora2pg vi /etc/ora2pg/ora2pg.conf.dist
 DATA_LIMIT 10000
 /usr/local/bin/ora2pg --project_base /home/oracle/ --init_project test_project
- 
Правим конфигурационный файл ora2pg: cd /home/oracle/test_project/config
 vi ora2pg.confORACLE_HOME /usr/lib/oracle/19.14/client64/libORACLE_DSN dbi:Oracle:host=zabbix.localhost;sid=zabbix;port=1521
 ORACLE_USER system
 ORACLE_PWD PasswordPG_DSN dbi:Pg:dbname=zabbix;host=localhost;port=5432
 PG_USER postgres
 PG_PWD Password
 PG_VERSION 14OUTPUT_DIR /opt/pgsql/14/data/migration
 EXPORT_SCHEMA 1
 SCHEMA zabbix
 PG_SCHEMA zabbix
 DEBUG 1
 PARALLEL_TABLES 35
 TRANSACTION readonlyDISABLE_TRIGGERS 0
zabbix.localhost - указываем ip адрес источника сервера с СУБД Oracle БД ZABBIX
- Создание пользователя и БД в СУБД PostgreSQL. 
             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_64psql -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 zabbixcreate 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. Всем добра :)
 
          