Zabbix – Migrace z MySQL do PostgreSQL

V tomto návodu si ukážeme, jak pro databázi Zabbixu provést migraci z MySQL do PostgreSQL na Rocky Linux 9.
Zároveň si také ukážeme, jak zapnout TimescaleDB spolu se základním performance tuningem.

Článek počítá s tím, že pokud jsou k dispozici volitelné patche (floatprimární klíče), pak byly do DB již aplikovány.
Pokud si nejste jisti, pak informace o tomto stavu se zobrazuje zároveň i ve frontendu v sekci System information, např. políčko: „Database history tables upgraded: No“.

Dopředu upozorňujeme, že migraci děláte pouze na vlastní nebezpečí a neneseme žádnou odpovědnost za případné škody způsobené neodborným zásahem.

Každá verze Zabbixu i databáze má svá konkrétní specifika, která je nutné brát v potaz už při návrhu migračního plánu a jednotlivých činností. Dle našich zkušeností se velká část problémů po migraci (například s promazáváním) může projevit až později. Doporučujeme tedy, abyste nás před zásahem do produkčního prostředí raději kontaktovali pro případnou konzultaci. Rádi vám s celým procesem bezchybné migrace a následnými kroky pomůžeme.

Kontrola verzí

Jako vůbec první krok před samotnou migrací je třeba vědět konkrétní aktuálně BĚŽÍCÍ verzi Zabbix serveru. Tedy nikoliv to, co nám zobrazuje patička ve webovém frontendu.

Toto nejbezpečněji zjistíme v logu samotného Zabbix serveru při jeho startu:

cat /var/log/zabbix/zabbix_server.log | grep "Starting Zabbix Server. Zabbix"

Výstup tohoto příkazu v našem případě vypadá následovně:

1933256:20240510:164211.482 Starting Zabbix Server. Zabbix 7.0.0 (revision 9bc845eca94)

Jako další možnost je zjištění verze instalačních balíčků podpůrných knihoven Zabbixu pro MySQL, což je ilustrováno příkazem níže.

Toto ale nemusí být skutečná, aktuálně běžící verze!

rpm -qa | grep zabbix-server-mysql

Výstup tohoto příkazu vypadá takto:

zabbix-server-mysql-7.0.0.release1.el9.x86_64

Dalším způsobem zjištění verze Zabbix serveru je pak kontrola verze samotným spouštěcím souborem. Ovšem i tato informace může být za jistých okolností zavádějící a nemusí to být verze aktuálně spuštěná.

zabbix_server -V

Výstup pak vypadá následovně:

zabbix_server (Zabbix) 7.0.0
Revision 9bc845eca94 30 January 2024, compilation time: Jan 30 2024 00:00:00

Přípravné kroky

MySQL triggery

Zabbix od verze 6.0.11 obsahuje databázové triggery a s těmi se musí při migraci počítat. Následující sadou příkazů tedy zjistíme, jestli se to naší databázové instance bude také týkat.

Přihlásíme se do mysql konzole:

mysql

Přepneme se do databáze ‚zabbix‘:

use zabbix;

Následně zavoláme příkaz SHOW TRIGGERS, který nám případně zobrazí použité databázové triggery:

SHOW TRIGGERS\G

Pokud je výstup tohoto příkazu následující, pak část s instalací triggerů níže v návodu můžete s klidem vynechat.

Empty set (0.00 sec)

Ukázku z výstupu tohoto příkazu v Zabbixu verze 6.0.11 vidíte zde. V tuto chvíli už se níže zmíněné kapitole o migraci triggerů nevyhnete.

*************************** 1. row ***************************
             Trigger: hosts_name_upper_insert
               Event: INSERT
               Table: hosts
           Statement: set new.name_upper=upper(new.name)
              Timing: BEFORE
             Created: 2024-02-27 09:59:58.09
            sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
             Definer: zabbix@localhost
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
  Database Collation: utf8mb4_bin
*************************** 2. row ***************************
             Trigger: hosts_name_upper_update
               Event: UPDATE
               Table: hosts
           Statement: begin
if new.name<>old.name
then
set new.name_upper=upper(new.name);
end if;
end
              Timing: BEFORE
             Created: 2024-02-27 09:59:58.10
            sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
             Definer: zabbix@localhost
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
  Database Collation: utf8mb4_bin
*************************** 3. row ***************************
             Trigger: items_name_upper_insert
               Event: INSERT
               Table: items
           Statement: set new.name_upper=upper(new.name)
              Timing: BEFORE
             Created: 2024-02-27 10:00:00.76
            sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
             Definer: zabbix@localhost
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
  Database Collation: utf8mb4_bin
*************************** 4. row ***************************
             Trigger: items_name_upper_update
               Event: UPDATE
               Table: items
           Statement: begin
if new.name<>old.name
then
set new.name_upper=upper(new.name);
end if;
end
              Timing: BEFORE
             Created: 2024-02-27 10:00:00.77
            sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
             Definer: zabbix@localhost
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
  Database Collation: utf8mb4_bin
4 rows in set (0.01 sec)

Instalace závislostí

Nejprve přidáme oficiální repozitář PostgreSQL, který pro instalaci doporučujeme. Instalační balíčky z repozitářů od RedHat se podstatně liší.

To provedeme následujícím příkazem:

yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm

Nainstalujeme PostgreSQL v Zabbixem podporované verzi, kterou zjistíme v matici kompatiblity na stránkách Zabbixu:

yum install postgresql16-server

Inicializujeme databázový server PostgreSQL následujícím příkazem:

/usr/pgsql-16/bin/postgresql-16-setup initdb

Spustíme službu PostgreSQL a nastavíme její spouštění po startu:

systemctl enable postgresql-16
systemctl start postgresql-16

Nainstalujeme utilitu pgloader, kterou použijeme k samotné migraci dat:

yum install pgloader

Pomocí následujícího příkazu zkontrolujeme verzi pgloaderu:

pgloader -V

Výstup bude pak vypadat následovně:

pgloader version "3.6.7"

Příprava na migraci

Nyní vytvoříme dočasnou složku, která nám bude sloužit k uchování konfiguračních souborů použitých při následné migraci a otevřeme ji:

mkdir /tmp/zabbix-db-migration/ && cd $_

Parsování schématu

Pro samotnou migraci dat budeme potřebovat soubor s databázovým schématem, tento nalezneme v oficiálních zdrojových kódech Zabbixu pro vaši konkrétní verzi.

Tento příkaz je nezbytně nutné přizpůsobit přímo vaší verzi Zabbix!

Stále se nacházíme v naší dočasné složce, vytvořené pro migraci a zdrojový kód pro naši verzi 7.0.0 tedy stáhneme sem, a to následujícím příkazem:

wget https://cdn.zabbix.com/zabbix/sources/stable/7.0/zabbix-7.0.0.tar.gz

Stáhnutý archiv se zdrojovým kódem Zabbixu rozbalíme:

tar -zxvf zabbix-7.0.0.tar.gz

Otevřeme si složku v následující cestě, kde nalezneme databázová schémata:

cd /tmp/zabbix-db-migration/zabbix-7.0.0/database/postgresql/

Z jednotného souboru schématu vybereme pouze operace vytvářející tabulky a triggery, a uložíme je do separátního souboru:

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

Tento soubor nyní obsahuje nejen CREATE TABLE operace, ale i operace a funkce pro triggery, které řešíme individuálně. Část, která triggery vytváří tedy z tohoto souboru odebereme:

sed -i '/create\ or\ replace\ function/,$d' /tmp/zabbix-db-migration/create_tables.sql

A z tohoto jednotného schématu pak právě vybereme pouze operace související s triggery:

awk '/INSERT INTO dbversion/{p=1;next} /ALTER TABLE/{p=0} p' schema.sql > /tmp/zabbix-db-migration/triggers.sql

A nyní můžeme postoupit dále. Ze stejného souboru s databázovým schématem vybreme pouze operace pro vytváření indexů a uložíme je v separátním souboru:

grep -E 'CREATE INDEX|CREATE UNIQUE INDEX' schema.sql > /tmp/zabbix-db-migration/create_index.sql

Opět z tohoto jednotného souboru se schématem vybereme pouze ALTER operace a uložíme je do separátního souboru:

grep 'ALTER TABLE ONLY' schema.sql > /tmp/zabbix-db-migration/alter_table.sql

Příprava PostgreSQL

Následně vytvoříme databázového uživatele pro Zabbix, budeme vyzváni k zadání hesla:

sudo -u postgres createuser --pwprompt zabbix

Vytvoříme zabbix databázi:

sudo -u postgres createdb -O zabbix zabbix

Vytvoříme zabbix schéma:

sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/create_tables.sql

Kvůli kompatibilitě s utilitou pgloader dočasně nastavíme encryption hash na ‚md5‘ a změníme heslo vytvořenému databázovému uživateli tak, aby se v daném hash algorytmu přegenerovalo. Pro jednoduchost použijte ideálně stejné heslo, jako jsme zadávali při vytváření tohoto uživatele.

sudo -u postgres psql -c "SET password_encryption='md5';"
sudo -u postgres psql -c "ALTER ROLE zabbix WITH PASSWORD '***********';"

Příprava MySQL

V případě, že naše MySQL používá již změněný formát přihlašování, pak je stejně jako u PostgreSQL pro potřeby pgloader třeba změnit způsob přihlašování databázového uživatele pro Zabbix a zároveň mu přegenerovat heslo. To uděláme následujícím způsobem.

Nejprve otevřeme konfigurační soubor MySQL serveru. Pokud používáte jinou verzi, např. MariaDB nebo Percona, pak se umístění může lišit.

nano /etc/my.cnf.d/mysql-server.cnf

A zde dočasně upravíme v sekci [mysqld] následující direktivu:

[mysqld]
...
default-authentication-plugin=mysql_native_password

Nyní musíme zrestartovat MySQL:

systemctl restart mysqld

A nyní můžeme změnit způsob přihlašování uživatele pro Zabbix a přegenerovat mu heslo. Nezapomeňte v příkazu níže změnit heslo na své vlastní!

mysql -e "ALTER USER 'zabbix'@'localhost' IDENTIFIED WITH mysql_native_password BY '*********';"

Připravíme konfiguraci – SQL skript pro pgloader, tudíž tento soubor vytvořte:

nano /tmp/zabbix-db-migration/pgloader.conf

A tento soubor vyplňte následujícím obsahem. Nezapomeňte si v tomto skriptu změnit hesla (označená pomocí hvězdiček) na vaše vlastní, validní hesla do obou databází:

LOAD DATABASE
FROM mysql://zabbix:**********@127.0.0.1/zabbix
INTO postgresql://zabbix:**********@127.0.0.1/zabbix
WITH include no drop,
truncate,
create no tables,
create no indexes,
no foreign keys,
reset sequences,
data only,
prefetch rows = 1000,
batch rows = 1000,
batch concurrency = 1
ALTER SCHEMA 'zabbix' RENAME TO 'public';

Migrace

Nyní se můžeme pustit do samotné migrace. V tuto chvíli doporučujeme udělat si zálohu zdrojové MySQL databáze a přesvědčte se, že máte dostatečné volné místo na disku.

Nejprve zastavíme službu Zabbix serveru a Apache web serveru pro Zabbix frontend:

systemctl stop zabbix-server httpd

Vytvoříme v naší dočasné složce složku pro migrovaná data z MySQL:

mkdir /tmp/zabbix-db-migration/data

A následně spustíme pgloader s námi vytvořeným konfiguračním souborem:

pgloader --root-dir=/tmp/zabbix-db-migration/data /tmp/zabbix-db-migration/pgloader.conf

Pokud pgloader při běhu zahlásí nějaké výstražné zprávy (Warning), pak je můžete směle ignorovat – ničemu nevadí. Naopak problémy, které jsou závažnější, a se kterými se ale také můžete setkat jsou např.: malý objem dostupného místa na disku, časové prodlevy mezi databázemi (timeouts), příliš nízká rychlost zápisu na disk (nízké iops). I tyto problémy lze vyřešit, ovšem vyžadují další analýzu a následný tuning přímo na míru.

Příklad výstupu tohoto příkazu naleznete zde:

2024-05-10T16:55:38.010000+01:00 LOG pgloader version "3.6.7~devel"
2024-05-10T16:55:38.174002+01:00 LOG Migrating from #<MYSQL-CONNECTION mysql://zabbix@127.0.0.1:3306/zabbix {100685C583}>
2024-05-10T16:55:38.175002+01:00 LOG Migrating into #<PGSQL-CONNECTION pgsql://zabbix@127.0.0.1:5432/zabbix {100685C713}>
2024-05-10T16:55:38.684006+01:00 WARNING Source column "public"."history_uint"."value" is casted to type "bigint" which is not the same as "numeric", the type of current target database column "public"."history_uint"."value".
2024-05-10T16:55:38.685006+01:00 WARNING Source column "public"."item_rtdata"."lastlogsize" is casted to type "bigint" which is not the same as "numeric", the type of current target database column "public"."item_rtdata"."lastlogsize".
2024-05-10T16:55:38.686006+01:00 WARNING Source column "public"."proxy_history"."lastlogsize" is casted to type "bigint" which is not the same as "numeric", the type of current target database column "public"."proxy_history"."lastlogsize".
2024-05-10T16:55:38.686006+01:00 WARNING Source column "public"."trends_uint"."value_min" is casted to type "bigint" which is not the same as "numeric", the type of current target database column "public"."trends_uint"."value_min".
2024-05-10T16:55:38.687006+01:00 WARNING Source column "public"."trends_uint"."value_avg" is casted to type "bigint" which is not the same as "numeric", the type of current target database column "public"."trends_uint"."value_avg".
2024-05-10T16:55:38.687006+01:00 WARNING Source column "public"."trends_uint"."value_max" is casted to type "bigint" which is not the same as "numeric", the type of current target database column "public"."trends_uint"."value_max".
2024-05-10T16:56:28.778334+01:00 ERROR Database error 23505: duplicate key value violates unique constraint "changelog_pkey"
DETAIL: Key (changelogid)=(16809) already exists.
CONTEXT: COPY changelog, line 1
2024-05-10T16:56:30.691348+01:00 LOG report summary reset
table name     errors       rows      bytes      total time
---------------------------------  ---------  ---------  ---------  --------------
fetch meta data          0        198                     0.121s
Truncate          0        198                     0.338s
---------------------------------  ---------  ---------  ---------  --------------
public.history          0    3899811   133.2 MB         39.021s
public.history_uint          0    2167293    66.0 MB         26.330s
public.trends          0     502182    27.5 MB          8.498s
public.items          0      12784     4.4 MB          1.488s
public.event_tag          0      13012   326.9 kB          0.942s
public.trigger_tag          0       7365   198.8 kB          1.411s
public.triggers          0       5546     1.4 MB          2.027s
public.graphs_items          0       4186   138.6 kB          2.082s
public.history_str          0       2923   233.3 kB          2.316s
public.item_condition          0       2445   123.0 kB          2.524s
public.widget_field          0       1875   103.9 kB          2.777s
public.graphs          0       1428   154.7 kB          3.150s
public.item_rtdata          0        957    16.0 kB          3.248s
public.host_tag          0        635    17.4 kB          3.486s
public.widget          0        467    14.2 kB          3.773s
public.host_hgset          0        307     2.5 kB          3.991s
public.profiles          0        265    13.2 kB          4.305s
public.dashboard_page          0        158     1.9 kB          4.515s
public.dashboard          0        154    10.5 kB          4.839s
public.images          0        187     1.9 MB          5.049s
public.task_check_now          0          0                     5.063s
public.lld_override_opdiscover          0         98     0.7 kB          5.114s
public.lld_override_opstatus          0         98     0.7 kB          5.217s
public.trigger_discovery          0         82     2.0 kB          5.339s
public.users_groups          0         64     0.5 kB          5.407s
public.user_ugset          0         61     0.3 kB          5.525s
public.graph_discovery          0         47     1.1 kB          5.643s
public.hosts_templates          0         31     0.5 kB          5.809s
public.problem          0         34     3.4 kB          6.004s
public.hstgrp          0         26     1.5 kB          6.212s
public.module          0         27     0.9 kB          6.343s
public.hgset          0         19     1.3 kB          6.497s
public.host_rtdata          0         13     0.1 kB          6.690s
public.expressions          0         10     0.5 kB          6.691s
public.escalations          0         15     0.7 kB          6.847s
public.permission          0          7     0.0 kB          6.810s
public.conditions          0          6     0.1 kB          6.961s
public.usrgrp          0          6     0.2 kB          6.958s
public.regexps          0          5     0.2 kB          7.101s
public.graph_theme          0          4     0.9 kB          7.071s
public.opmessage_grp          0          4     0.0 kB          7.248s
public.httpstepitem          0          3     0.0 kB          7.275s
public.scripts          0          3     0.3 kB          7.423s
public.sysmaps_links          0          3     0.4 kB          7.411s
public.acknowledges          0          1     0.0 kB          7.573s
public.interface_snmp          0          2     0.1 kB          7.510s
public.proxy          0          2     0.1 kB          7.738s
public.ugset          0          2     0.1 kB          7.531s
public.dchecks          0          1     0.0 kB          7.727s
public.autoreg_host          0          0                     7.722s
public.config_autoreg_tls          0          1     0.0 kB          7.899s
public.connector_tag          0          0                     7.852s
public.corr_condition_group          0          0                     7.925s
public.corr_condition_tagpair          0          0                     8.054s
public.corr_operation          0          0                     8.049s
public.dashboard_user          0          0                     8.200s
public.dhosts          0          1     0.0 kB          8.190s
public.dservices          0          1     0.2 kB          8.298s
public.globalmacro          0          1     0.0 kB          8.291s
public.group_discovery          0          0                     8.472s
public.history_log          0          0                     8.467s
public.httpstep          0          1     0.1 kB          8.693s
public.httptest          0          1     0.1 kB          8.688s
public.httptest_tag          0          0                     8.849s
public.icon_mapping          0          0                     8.821s
public.lld_override_ophistory          0          0                     9.102s
public.lld_override_opperiod          0          0                     8.981s
public.lld_override_optag          0          0                     9.132s
public.lld_override_optrends          0          0                     9.350s
public.maintenances          0          1     0.0 kB          9.347s
public.maintenances_hosts          0          1     0.0 kB          9.557s
public.opcommand          0          0                     9.548s
public.opcommand_hst          0          0                     9.736s
public.opgroup          0          1     0.0 kB          9.738s
public.opmessage_usr          0          0                     9.954s
public.optemplate          0          1     0.0 kB          9.950s
public.proxy_dhistory          0          0                    10.057s
public.report          0          0                    10.101s
public.report_user          0          0                    10.120s
public.scim_group          0          0                    10.198s
public.service_alarms          0          0                    10.219s
public.service_problem_tag          0          0                    10.271s
public.service_tag          0          0                    10.329s
public.services_links          0          0                    10.363s
public.sla_excluded_downtime          0          0                    10.401s
public.sla_service_tag          0          0                    10.487s
public.sysmap_element_url          0          0                    10.484s
public.sysmap_url          0          0                    10.618s
public.sysmap_usrgrp          0          0                    10.537s
public.sysmaps_link_triggers          0          0                    10.622s
public.task          0          0                    10.677s
public.task_close_problem          0          0                    10.752s
public.task_remote_command          0          0                    10.763s
public.task_result          0          0                    10.812s
public.token          0          0                    10.864s
public.user_scim_group          0          0                    10.940s
public.userdirectory_idpgroup          0          0                    10.955s
public.userdirectory_media          0          0                    11.072s
public.userdirectory_usrgrp          0          0                    11.029s
public.valuemap_mapping          0      30621   861.6 kB         11.359s
public.trends_uint          0     345750    11.3 MB          3.151s
public.item_tag          0      19823   598.5 kB          0.772s
public.item_preproc          0      11373   603.2 kB          0.888s
public.functions          0       9445   268.0 kB          1.304s
public.item_discovery          0       5629   129.7 kB          1.377s
public.hostmacro          0       4612   360.1 kB          1.518s
public.events          0       3494   252.6 kB          1.644s
public.alerts          0       3083   844.7 kB          1.838s
public.trigger_depends          0       1819    32.0 kB          2.011s
public.auditlog          0       5350   642.1 kB          2.329s
public.event_recovery          0       1362    27.6 kB          2.490s
public.item_rtname          0        917    60.6 kB          2.691s
public.media_type_param          0        555    22.0 kB          2.867s
public.hosts          0        318   133.3 kB          3.229s
public.hosts_groups          0        307     3.7 kB          3.413s
public.history_text          0        211     3.7 MB          3.957s
public.media_type_message          0        154    41.1 kB          4.150s
public.event_suppress          0        143     3.5 kB          4.421s
public.lld_macro_path          0        134     4.5 kB          4.481s
public.problem_tag          0        150     3.6 kB          4.600s
public.lld_override_operation          0         98     2.9 kB          4.726s
public.lld_override          0         95     3.7 kB          4.842s
public.lld_override_condition          0         85     3.6 kB          4.946s
public.users          0         63     7.8 kB          5.092s
public.ids          0         51     1.3 kB          5.177s
public.item_parameter          0         43     1.7 kB          5.288s
public.group_prototype          0         28     0.9 kB          5.371s
public.role_rule          0         27     0.8 kB          5.505s
public.interface          0         24     1.1 kB          5.670s
public.media_type          0         31   256.8 kB          5.707s
public.hgset_group          0         19     0.1 kB          5.649s
public.host_discovery          0         11     0.2 kB          5.789s
public.operations          0         10     0.2 kB          5.792s
public.opmessage          0          8     0.1 kB          5.806s
public.rights          0          7     0.1 kB          5.872s
public.sessions          0          6     0.5 kB          5.985s
public.actions          0          5     0.3 kB          5.883s
public.sysmaps_elements          0          5     0.8 kB          5.978s
public.housekeeper          0          4     0.1 kB          5.993s
public.role          0          4     0.1 kB          5.966s
public.httptestitem          0          3     0.0 kB          6.161s
public.sysmaps          0          3     0.2 kB          6.102s
public.ugset_group          0          3     0.0 kB          6.098s
public.dashboard_usrgrp          0          2     0.0 kB          6.088s
public.media          0          3     0.1 kB          6.262s
public.proxy_rtdata          0          2     0.0 kB          6.239s
public.config          0          1     0.7 kB          6.237s
public.ha_node          0          1     0.1 kB          6.223s
public.changelog          1          0                     6.382s
public.connector          0          0                     6.371s
public.corr_condition          0          0                     6.354s
public.corr_condition_tag          0          0                     6.365s
public.corr_condition_tagvalue          0          0                     6.487s
public.correlation          0          0                     6.505s
public.dbversion          0          1     0.0 kB          6.513s
public.drules          0          1     0.0 kB          6.500s
public.event_symptom          0          0                     6.610s
public.globalvars          0          1     0.0 kB          6.631s
public.history_bin          0          0                     6.634s
public.host_inventory          0          1     0.3 kB          6.640s
public.httpstep_field          0          0                     6.735s
public.httptest_field          0          0                     6.747s
public.icon_map          0          0                     6.771s
public.interface_discovery          0          0                     6.767s
public.lld_override_opinventory          0          0                     6.868s
public.lld_override_opseverity          0          0                     6.883s
public.lld_override_optemplate          0          0                     6.908s
public.maintenance_tag          0          0                     6.906s
public.maintenances_groups          0          0                     7.003s
public.maintenances_windows          0          1     0.0 kB          7.016s
public.opcommand_grp          0          0                     7.036s
public.opconditions          0          0                     7.031s
public.opinventory          0          0                     7.129s
public.optag          0          0                     7.147s
public.proxy_autoreg_host          0          0                     7.178s
public.proxy_history          0          0                     7.191s
public.report_param          0          0                     7.224s
public.report_usrgrp          0          0                     7.305s
public.script_param          0          0                     7.244s
public.service_problem          0          0                     7.348s
public.service_status_rule          0          0                     7.366s
public.services          0          0                     7.318s
public.sla          0          0                     7.411s
public.sla_schedule          0          0                     7.473s
public.sysmap_element_trigger          0          0                     7.455s
public.sysmap_shape          0          1     0.1 kB          7.407s
public.sysmap_user          0          0                     7.582s
public.sysmaps_element_tag          0          0                     7.602s
public.tag_filter          0          0                     7.517s
public.task_acknowledge          0          0                     7.653s
public.task_data          0          0                     7.574s
public.task_remote_command_result          0          0                     7.725s
public.timeperiods          0          1     0.0 kB          7.643s
public.trigger_queue          0          0                     7.726s
public.userdirectory          0          0                     7.770s
public.userdirectory_ldap          0          0                     7.744s
public.userdirectory_saml          0          0                     7.785s
public.valuemap          0        944    62.8 kB          7.835s
---------------------------------  ---------  ---------  ---------  --------------
COPY Threads Completion          0          4                    51.236s
Reset Sequences          0          1                     0.110s
Install Comments          0          0                     0.000s
---------------------------------  ---------  ---------  ---------  --------------
Total import time          1    7071507   255.7 MB         51.346s

Ve chvíli, kdy nám pgloader úspěšně doběhne, nastavení hashovacího algorytmu vrátíme zpět na bezpečnější hodnotu ‚SCRAM-SHA-256‘ a databázovému uživateli opět přegenerujeme heslo. Hvězdičky v následujícím příkazu nahraďte vámi zvoleným heslem:

sudo -u postgres psql -c "SET password_encryption='SCRAM-SHA-256';"
sudo -u postgres psql -c "ALTER ROLE zabbix WITH PASSWORD '************';"

Následně vytvoříme schéma pro indexy:

sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/create_index.sql

Následně pak schéma pro alter table:

sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/alter_table.sql

A nakonec i schéma pro triggers:

sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/triggers.sql

Po úspěšné migraci doporučujeme spustit VACUUM:

sudo -u postgres vacuumdb --dbname=zabbix --analyze --username=postgres --jobs=$(grep -c processor /proc/cpuinfo)

Testování funkčnosti

Nejprve odstraníme podporu MySQL pro Zabbix a MySQL frontend:

yum remove zabbix-server-mysql zabbix-web-mysql

Nainstalujeme závislosti potřebné pro běh Zabbix serveru s PostgreSQL včetně frontendu.

Pozor: Reinstalací Zabbix serveru se ztratí konfigurace v souboru zabbix_server.conf! Doporučujeme zálohu!

yum install zabbix-server-pgsql zabbix-web-pgsql zabbix-apache-conf

Otevřeme konfigurační soubor Zabbix serveru:

nano /etc/zabbix/zabbix_server.conf

A zde upravíme direktivu pro přístup do databáze na nové přístupové údaje pro PostgreSQL. Hvězdičky nahraďte aktuálním heslem uživatele ‚zabbix‘:

DBPassword=*******

Odebereme starý konfigurační soubor frontendu pro MySQL:

rm /etc/zabbix/web/zabbix.conf.php

Zrestartujeme Zabbix server a Apache web server:

systemctl restart zabbix-server httpd

Zkontrolujeme log Zabbixu, abychom se ujistili, že všechno naběhlo v pořádku a bez jakýchkoliv problémů.

nano /var/log/zabbix/zabbix_server.log

Pomocí prohlížeče se připojíme na URL Zabbix frontendu a znovu frontend nastavíme, tentokrát pro PostgreSQL.

Nejprve nás přivítá úvodní obrazovka s volbou jazyka:

zabbix install - welcome page

Následuje kontrola požadovaných verzí a nastavení, kde již můžeme vidět nainstalovanou podporu pro PostgreSQL:

zabbix install - pre-requisites

V dalším kroku nás čeká nastavení databáze, kde vyplníme přihlašovací údaje vytvořené v předchozích krocích:

zabbix install - database config

Vybereme název Zabbix serveru, časové pásmo a implicitní téma:

zabbix install - settings

Pak už zbývá jen zkontrolovat, že máme všechno nastavené správně a tyto volby potvrdit:

zabbix install - review

A nyní máme úspěšně napojený Zabbix frontend na PostgreSQL!

zabbix install final step

V tuto chvíli můžeme zastavit MySQL server:

systemctl stop mysqld

A MySQL lze nyní i zcela odinstalovat. Data (ve standardní cestě /var/lib/mysql) nebudou smazána, ale doporučujeme je např. po 14 dnech funkčního provozu s PostgreSQL smazat.

yum remove mysql

TimescaleDB

Potom, co jsme úspěšně zmigrovali z MySQL do PostgreSQL se nám zároveň nabízí možnost ještě více zvýšit výkonnost Zabbixu pomocí TimescaleDB.

Vzhledem k tomu, že už máme rozbalený soubor se zdrojovým kódem, který obsahuje i databázová instalační schámata, můžeme rovnou přistoupit instalaci.

Začneme tím, že přidáme oficiální repozitář:

tee /etc/yum.repos.d/timescale_timescaledb.repo <<EOL
[timescale_timescaledb]
name=timescale_timescaledb
baseurl=https://packagecloud.io/timescale/timescaledb/el/$(rpm -E %{rhel})/\$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/timescale/timescaledb/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
EOL

Nainstalujme potřebné balíčky:

yum install timescaledb-2-postgresql-16 timescaledb-2-loader-postgresql-16

Spustíme utilitu timescaledb-tune a jako parametr jí předáme vyšší hodnotu maximálního množství připojení (--max-conns), které pro tyto testovací účely nastavíme na 125.

Tato utilita slouží k přizpůsobení výchozího nastavení PostgreSQL směrem k výkonu a adekvátnímu nastavení parametrů PostgreSQL pro fungování s TimescaleDB.

Zároveň nám tato utilit pomocí instalačního průvodce pomůže vybrat aktuální a platný konfigurační soubor PostgreSQL a nastaví i automatické načítání knihoven TimescaleDB.

Prosím, odpovídejte „ano“ (y) na všechny otázky.

timescaledb-tune --pg-config /usr/pgsql-16/bin --max-conns=125
timescaledb-tune

Následně vypneme Zabbix server a restartujeme systémovou službu PostgreSQL:

systemctl stop zabbix-server
systemctl restart postgresql-16

Aktivujeme TimescaleDB pro databázi Zabbixu:

echo "CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;" | sudo -u postgres psql --dbname=zabbix

A načíst data z rozbaleného souboru databázového schématu:

sudo -u postgres psql --host=127.0.0.1 --dbname=zabbix --username=zabbix -f /tmp/zabbix-db-migration/zabbix-7.0.0beta1/database/postgresql/timescaledb/schema.sql
timescaledb installation

Nyní můžeme opětovně nastartovat službu Zabbix serveru.

systemctl start zabbix-server

V případě, že uvidíte v log souboru zprávu o tom, že je verze TimescaleDB příliš nová, pak to není žádný velký problém. Zabbix nedokáže dostatečně rychle reagovat na nejnovější verze TimescaleDB tak, aby ji ve svém kódu nastavil jako podporovanou, ovšem kompatibilita je Zabbixem zaručena a námi ověřena.

Pokud se chceme vyhnout zprávám o nekompatibilitě v log souboru Zabbixu, pak stačí otevřít konfigurační soubor Zabbix serveru v cestě /etc/zabbix/zabbix_server.conf a zde upravte následující konfigurační parametr:

AllowUnsupportedDBVersions=1

Soubor s tímto nastavením uložte a znovu nastartujte systémovou službu Zabbix serveru.

systemctl start zabbix-server

A to je vše! Nyní jste se naučili, jak zmigrovat Zabbix databázi z MySQL do PostgreSQL, dále se vám podařilo zprovoznit výkonnou TimescaleDB a máte základní performance tuning. Následující kroky by měly smeřovat k zálohování a monitoringu DB.