3 Database upgrade to primary keys

Przegląd

Ta sekcja zawiera instrukcje dotyczące ręcznej aktualizacji tabel w istniejących instalacjach do kluczy głównych.

Aktualizacja do kluczy głównych optymalizuje sposób indeksowania danych i uzyskiwania do nich dostępu, co może przyspieszyć zapytania i zaoszczędzić miejsce. Poprawia także zarządzanie danymi i synchronizację w środowiskach klastrowych, pomagając w skalowaniu i zapewniając niezawodność systemu nawet w przypadku awarii niektórych serwerów.

Instrukcje podane na tej stronie są przeznaczone dla zaawansowanych użytkowników i mogą wymagać dostosowania do konkretnej konfiguracji. Aktualizacja do kluczy głównych może być czasochłonna i zasobochłonna. Upewnij się, że dostępna jest wystarczająca ilość wolnego miejsca na dysku; w zależności od rozmiaru bazy danych i przechowywanych danych proces może wymagać nawet 2,5 razy więcej miejsca niż obecnie zajmują tabele historii.

Klucze główne są używane we wszystkich tabelach w nowych instalacjach od Zabbix 6.0.

Nie ma automatycznej aktualizacji bazy danych do kluczy głównych; jednak istniejące instalacje można zaktualizować ręcznie po aktualizacji serwera Zabbix do wersji 6.0 lub nowszej.

Od Zabbix 7.0 aktualizacja tabel do kluczy głównych obejmuje również aktualizację tabel do używania typów danych double precision.

Jeśli używasz Zabbix 7.0 (lub nowszego), tabele już korzystają z typu double precision. Jednak instrukcje na tej stronie nadal można zastosować, aby zaktualizować tabele do kluczy głównych bez wpływu na tabele, które już używają typu double precision.

Jeśli używasz Zabbix 6.4 (lub wcześniejszego), rozważ najpierw aktualizację tabel do typu double precision. Więcej informacji można znaleźć w sekcji Upgrading to numeric values of extended range w dokumentacji Zabbix 7.0.

Dostępne są instrukcje dla:

Ważne uwagi

Aby przeprowadzić aktualizację bazy danych:

  1. Zatrzymaj serwer Zabbix.

Zdecydowanie zaleca się zatrzymanie serwera Zabbix na czas aktualizacji. Jeśli jednak jest to absolutnie konieczne, możesz przeprowadzić aktualizację, gdy serwer działa (dotyczy tylko MySQL, MariaDB oraz PostgreSQL bez TimescaleDB).

  1. Wykonaj kopię zapasową bazy danych.
  2. Zainstaluj najnowszy pakiet zabbix-sql-scripts zgodny z używaną wersją Zabbix (np. dla RHEL: dnf install zabbix-sql-scripts).
  3. Uruchom skrypty dla swojej bazy danych.
  4. Uruchom serwer Zabbix.

Uruchom skrypty tylko dla bazy danych serwera. proxy nie odniesie korzyści z tej aktualizacji.

Jeśli baza danych używa partycji, skontaktuj się z administratorem DB lub pomocą techniczną Zabbix.

Pliki CSV można usunąć po pomyślnej aktualizacji do kluczy głównych.

Opcjonalnie frontend Zabbix można przełączyć w tryb konserwacji.

MySQL

Eksport i import muszą być wykonywane w tmux/screen, aby zapewnić, że sesja nie zostanie przerwana.

Zobacz także: Ważne uwagi

MySQL 8.4+ z mysqlsh

Ta metoda może być używana z działającym serwerem Zabbix, jednak zaleca się zatrzymanie serwera na czas aktualizacji. MySQL Shell (mysqlsh) musi być zainstalowany i mieć możliwość połączenia z bazą danych.

  • Zaloguj się do konsoli MySQL jako root (zalecane) lub jako dowolny użytkownik z uprawnieniami FILE.

  • Uruchom MySQL z włączoną zmienną local_infile.

  • Zmień nazwy starych tabel i utwórz nowe tabele, uruchamiając history_upgrade_prepare.sql.

mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
  • Wyeksportuj i zaimportuj dane.

Połącz się przez mysqlsh. W przypadku używania połączenia przez socket może być wymagane podanie ścieżki.

sudo mysqlsh -uroot -S /run/mysqld/mysqld.sock --no-password -Dzabbix

Przełącz się do trybu JavaScript, używając:

\js

Następnie uruchom poniższy kod (CSVPATH można zmienić w razie potrzeby):

CSVPATH="/var/lib/mysql-files";

util.exportTable("history_old", CSVPATH + "/history.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history.csv", {"dialect": "csv", "table": "history" });

util.exportTable("history_uint_old", CSVPATH + "/history_uint.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_uint.csv", {"dialect": "csv", "table": "history_uint" });

util.exportTable("history_str_old", CSVPATH + "/history_str.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_str.csv", {"dialect": "csv", "table": "history_str" });

util.exportTable("history_log_old", CSVPATH + "/history_log.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_log.csv", {"dialect": "csv", "table": "history_log" });

util.exportTable("history_text_old", CSVPATH + "/history_text.csv", { dialect: "csv" });
util.importTable(CSVPATH + "/history_text.csv", {"dialect": "csv", "table": "history_text" });

Jeśli otrzymasz komunikat „JavaScript is not supported”, oznacza to, że Twoja instalacja MySQL Shell nie ma obsługi JS. W takim przypadku zainstaluj oficjalny pakiet MySQL Shell od Oracle (lub zbuduj go ze źródeł), aby tryb JavaScript był dostępny.

MariaDB/MySQL 8.4+ bez mysqlsh

Ta metoda aktualizacji zajmuje więcej czasu i powinna być używana tylko wtedy, gdy aktualizacja z użyciem mysqlsh nie jest możliwa.

Aktualizacja tabel
  • Zaloguj się do konsoli MySQL jako root (zalecane) lub dowolny użytkownik z uprawnieniami FILE.

  • Jeśli przeprowadzasz migrację przy działającym serwer Zabbix, uruchom MySQL z włączoną zmienną local_infile.

  • Zmień nazwy starych tabel i utwórz nowe tabele, uruchamiając history_upgrade_prepare.sql:

mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
Migracja przy zatrzymanym serwerze

Przed migracją danych należy wyłączyć max_execution_time (w MySQL) lub max_statement_time (w MariaDB), aby uniknąć przekroczenia limitu czasu podczas migracji.

Dla MySQL:

SET @@max_execution_time=0;

Dla MariaDB:

SET @@max_statement_time=0;
INSERT IGNORE INTO history SELECT * FROM history_old;
INSERT IGNORE INTO history_uint SELECT * FROM history_uint_old;
INSERT IGNORE INTO history_str SELECT * FROM history_str_old;
INSERT IGNORE INTO history_log SELECT * FROM history_log_old;
INSERT IGNORE INTO history_text SELECT * FROM history_text_old;

Aby usunąć stare tabele, postępuj zgodnie z instrukcjami po migracji.

Migracja przy działającym serwerze

Sprawdź, dla których ścieżek włączono import/eksport:

mysql> SELECT @@secure_file_priv;
+-----------------------+
| @@secure_file_priv    |
+-----------------------+
| /var/lib/mysql-files/ |
+-----------------------+

Jeśli wartość secure_file_priv jest ścieżką do katalogu, eksport/import będzie wykonywany dla plików w tym katalogu. W takim przypadku odpowiednio zmień ścieżki do plików w zapytaniach lub ustaw wartość secure_file_priv na pusty ciąg na czas aktualizacji.

Jeśli wartość secure_file_priv jest pusta, eksport/import może być wykonywany z dowolnej lokalizacji.

Jeśli wartość secure_file_priv ma wartość NULL, ustaw ją na ścieżkę zawierającą wyeksportowane dane tabeli ('/var/lib/mysql-files/' w powyższym przykładzie).

Więcej informacji można znaleźć w dokumentacji MySQL lub dokumentacji MariaDB.

Przed eksportem danych należy wyłączyć max_execution_time (w MySQL) lub max_statement_time (w MariaDB), aby uniknąć przekroczenia limitu czasu podczas eksportu.

Dla MySQL:

SET @@max_execution_time=0;

Dla MariaDB:

SET @@max_statement_time=0;
SELECT * INTO OUTFILE '/var/lib/mysql-files/history.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_old;
LOAD DATA INFILE '/var/lib/mysql-files/history.csv' IGNORE INTO TABLE history FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';

SELECT * INTO OUTFILE '/var/lib/mysql-files/history_uint.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_uint_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_uint.csv' IGNORE INTO TABLE history_uint FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';

SELECT * INTO OUTFILE '/var/lib/mysql-files/history_str.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_str_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_str.csv' IGNORE INTO TABLE history_str FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';

SELECT * INTO OUTFILE '/var/lib/mysql-files/history_log.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_log_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_log.csv' IGNORE INTO TABLE history_log FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';

SELECT * INTO OUTFILE '/var/lib/mysql-files/history_text.csv' FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n' FROM history_text_old;
LOAD DATA INFILE '/var/lib/mysql-files/history_text.csv' IGNORE INTO TABLE history_text FIELDS TERMINATED BY ',' ESCAPED BY '"' LINES TERMINATED BY '\n';

Aby usunąć stare tabele, postępuj zgodnie z instrukcjami po migracji.

PostgreSQL

Eksport i import należy wykonać w tmux/screen, aby mieć pewność, że sesja nie zostanie przerwana. W przypadku instalacji z TimescaleDB pomiń tę sekcję i przejdź do PostgreSQL + TimescaleDB.

Zobacz także: Ważne uwagi

Aktualizacja tabel

  • Zmień nazwy tabel za pomocą history_upgrade_prepare.sql:
sudo -u zabbix psql zabbix < /usr/share/zabbix/sql-scripts/postgresql/option-patches/history_upgrade_prepare.sql

Migracja przy zatrzymanym serwerze

  • Wyeksportuj bieżące dane historyczne, zaimportuj je do tabeli tymczasowej, a następnie wstaw dane do nowych tabel, ignorując duplikaty:
INSERT INTO history SELECT * FROM history_old ON CONFLICT (itemid,clock,ns) DO NOTHING;

INSERT INTO history_uint SELECT * FROM history_uint_old ON CONFLICT (itemid,clock,ns) DO NOTHING;

INSERT INTO history_str SELECT * FROM history_str_old ON CONFLICT (itemid,clock,ns) DO NOTHING;

INSERT INTO history_log SELECT * FROM history_log_old ON CONFLICT (itemid,clock,ns) DO NOTHING;

INSERT INTO history_text SELECT * FROM history_text_old ON CONFLICT (itemid,clock,ns) DO NOTHING;

Zobacz wskazówki dotyczące poprawy wydajności operacji INSERT: PostgreSQL: Bulk Loading Huge Amounts of Data, Checkpoint Distance and Amount of WAL.

Migracja przy działającym serwerze

  • Wyeksportuj bieżącą historię, zaimportuj ją do tabeli tymczasowej, a następnie wstaw dane do nowych tabel, ignorując duplikaty:
\copy history_old TO '/tmp/history.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history (
    itemid                   bigint                                    NOT NULL,
    clock                    integer         DEFAULT '0'               NOT NULL,
    value                    DOUBLE PRECISION DEFAULT '0.0000'          NOT NULL,
    ns                       integer         DEFAULT '0'               NOT NULL
);
\copy temp_history FROM '/tmp/history.csv' DELIMITER ',' CSV
INSERT INTO history SELECT * FROM temp_history ON CONFLICT (itemid,clock,ns) DO NOTHING;

\copy history_uint_old TO '/tmp/history_uint.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_uint (
    itemid                   bigint                                    NOT NULL,
    clock                    integer         DEFAULT '0'               NOT NULL,
    value                    numeric(20)     DEFAULT '0'               NOT NULL,
    ns                       integer         DEFAULT '0'               NOT NULL
);
\copy temp_history_uint FROM '/tmp/history_uint.csv' DELIMITER ',' CSV
INSERT INTO history_uint SELECT * FROM temp_history_uint ON CONFLICT (itemid,clock,ns) DO NOTHING;

\copy history_str_old TO '/tmp/history_str.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_str (
    itemid                   bigint                                    NOT NULL,
    clock                    integer         DEFAULT '0'               NOT NULL,
    value                    varchar(255)    DEFAULT ''                NOT NULL,
    ns                       integer         DEFAULT '0'               NOT NULL
);
\copy temp_history_str FROM '/tmp/history_str.csv' DELIMITER ',' CSV
INSERT INTO history_str (itemid,clock,value,ns) SELECT * FROM temp_history_str ON CONFLICT (itemid,clock,ns) DO NOTHING;

\copy history_log_old TO '/tmp/history_log.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_log (
    itemid                   bigint                                    NOT NULL,
    clock                    integer         DEFAULT '0'               NOT NULL,
    timestamp                integer         DEFAULT '0'               NOT NULL,
    source                   varchar(64)     DEFAULT ''                NOT NULL,
    severity                 integer         DEFAULT '0'               NOT NULL,
    value                    text            DEFAULT ''                NOT NULL,
    logeventid               integer         DEFAULT '0'               NOT NULL,
    ns                       integer         DEFAULT '0'               NOT NULL
);
\copy temp_history_log FROM '/tmp/history_log.csv' DELIMITER ',' CSV
INSERT INTO history_log SELECT * FROM temp_history_log ON CONFLICT (itemid,clock,ns) DO NOTHING;

\copy history_text_old TO '/tmp/history_text.csv' DELIMITER ',' CSV
CREATE TEMP TABLE temp_history_text (
    itemid                   bigint                                    NOT NULL,
    clock                    integer         DEFAULT '0'               NOT NULL,
    value                    text            DEFAULT ''                NOT NULL,
    ns                       integer         DEFAULT '0'               NOT NULL
);
\copy temp_history_text FROM '/tmp/history_text.csv' DELIMITER ',' CSV
INSERT INTO history_text SELECT * FROM temp_history_text ON CONFLICT (itemid,clock,ns) DO NOTHING;

PostgreSQL + TimescaleDB

Eksport i import muszą być wykonywane w tmux/screen, aby zapewnić, że sesja nie zostanie przerwana. serwer Zabbix powinien być wyłączony podczas aktualizacji.

Zobacz także: Ważne uwagi

  • Zmień nazwy tabel za pomocą history_upgrade_prepare.sql.

    • Jeśli kompresja jest włączona (w domyślnej instalacji), uruchom skrypt z /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression:
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_prepare.sql | sudo -u zabbix psql zabbix
    • Jeśli kompresja jest wyłączona, uruchom skrypt z /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression:
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_prepare.sql | sudo -u zabbix psql zabbix
  • Uruchom skrypty migracji hypertable TimescaleDB zgodnie z ustawieniami kompresji:

    • Jeśli kompresja jest włączona (w domyślnej instalacji), uruchom skrypty z /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression:
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_uint.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_log.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_str.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/history_upgrade_text.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/with-compression/trends_upgrade.sql | sudo -u zabbix psql zabbix
    • Jeśli kompresja jest wyłączona, uruchom skrypty z /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression:
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_uint.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_log.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_str.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/history_upgrade_text.sql | sudo -u zabbix psql zabbix
      cat /usr/share/zabbix/sql-scripts/postgresql/timescaledb/option-patches/without-compression/trends_upgrade.sql | sudo -u zabbix psql zabbix

Zobacz także: Wskazówki dotyczące poprawy wydajności INSERT.

Po migracji

Dla wszystkich baz danych, po zakończeniu migracji wykonaj następujące czynności:

  • Zweryfikuj, że wszystko działa zgodnie z oczekiwaniami.

  • Usuń stare tabele:

DROP TABLE history_old;
DROP TABLE history_uint_old;
DROP TABLE history_str_old;
DROP TABLE history_log_old;
DROP TABLE history_text_old;
  • W przypadku TimescaleDB usuń również następującą starą tabelę:
DROP TABLE trends_old;

Zobacz także