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.0+ z mysqlsh

Ta metoda może być używana przy działającym serwerze Zabbix, ale zaleca się zatrzymanie serwera na czas aktualizacji. MySQL Shell (mysqlsh) musi być zainstalowany i musi 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. Jeśli używasz połączenia socket, może być wymagane podanie ścieżki.

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

Przełącz się w tryb JavaScript, używając:

\js

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

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 pojawi się komunikat "JavaScript is not supported", oznacza to, że instalacja MySQL Shell nie obsługuje JS. W takim przypadku zainstaluj oficjalny pakiet MySQL Shell firmy Oracle (lub zbuduj go ze źródeł), aby włączyć tryb JavaScript.

MariaDB/MySQL 8.0+ bez mysqlsh

Ta metoda aktualizacji trwa dłużej 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 wykonujesz migrację przy działającym serwerze 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

max_execution_time (w MySQL) lub max_statement_time (w MariaDB) musi zostać wyłączona przed migracją danych, 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;

Postępuj zgodnie z instrukcjami po migracji, aby usunąć stare tabele.

Migracja przy działającym serwerze

Sprawdź, dla jakich ścieżek włączony jest 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 albo ustaw wartość secure_file_priv na pusty ciąg znaków 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 tabel ('/var/lib/mysql-files/' w powyższym przykładzie).

Więcej informacji znajdziesz w dokumentacji MySQL lub dokumentacji MariaDB.

max_execution_time (w MySQL) lub max_statement_time (w MariaDB) musi zostać wyłączona przed eksportem danych, 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';

Postępuj zgodnie z instrukcjami po migracji, aby usunąć stare tabele.

PostgreSQL

Eksport i import należy wykonać w tmux/screen, aby upewnić się, ż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, używając 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żącą historię, zaimportuj ją 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 INSERT: PostgreSQL: Bulk Loading Huge Amounts of Data, Checkpoint Distance and Amount of WAL.

Migracja z działającym serwerem

  • 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 upewnić się, że sesja nie zostanie przerwana. Serwer Zabbix powinien być wyłączony podczas aktualizacji.

Zobacz także: Important notes

  • Zmień nazwy tabel, używając 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 w zależności od ustawień 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: Tips 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