3 Aggiornamento del database alle chiavi primarie

Panoramica

Questa sezione fornisce istruzioni per aggiornare manualmente le tabelle nelle installazioni esistenti alle chiavi primarie.

L'aggiornamento alle chiavi primarie ottimizza il modo in cui i dati vengono indicizzati e consultati, il che può velocizzare le query e risparmiare spazio. Migliora inoltre la gestione e la sincronizzazione dei dati nelle configurazioni cluster, facilitando la scalabilità e garantendo che il sistema rimanga affidabile anche in caso di guasto di alcuni server.

Le istruzioni fornite in questa pagina sono pensate per utenti avanzati e potrebbero dover essere adattate alla configurazione specifica in uso. L'aggiornamento alle chiavi primarie può richiedere molto tempo e molte risorse. Assicurarsi che sia disponibile spazio libero su disco sufficiente; a seconda delle dimensioni del database e dei dati memorizzati, il processo potrebbe richiedere fino a 2,5 volte lo spazio attualmente utilizzato dalle tabelle dello storico.

Le chiavi primarie vengono utilizzate per tutte le tabelle nelle nuove installazioni a partire da Zabbix 6.0.

Non esiste un aggiornamento automatico del database alle chiavi primarie; tuttavia, le installazioni esistenti possono essere aggiornate manualmente dopo aver aggiornato Zabbix server alla versione 6.0 o successiva.

A partire da Zabbix 7.0, l'aggiornamento delle tabelle alle chiavi primarie aggiorna anche le tabelle affinché utilizzino tipi di dati double precision.

Se si utilizza Zabbix 7.0 (o successivo), le tabelle utilizzano già double precision. Tuttavia, è comunque possibile seguire le istruzioni in questa pagina per aggiornare le tabelle alle chiavi primarie senza influire sulle tabelle che utilizzano già double precision.

Se si utilizza Zabbix 6.4 (o precedente), valutare prima l'aggiornamento delle tabelle a double precision. Per ulteriori informazioni, vedere Upgrading to numeric values of extended range nella documentazione di Zabbix 7.0.

Sono disponibili istruzioni per:

Note importanti

Per eseguire l'aggiornamento del database:

  1. Arrestare Zabbix server.

Si consiglia vivamente di arrestare Zabbix server per la durata dell'aggiornamento. Tuttavia, se strettamente necessario, è possibile eseguire l'aggiornamento mentre il server è in esecuzione (solo per MySQL, MariaDB e PostgreSQL senza TimescaleDB).

  1. Eseguire un backup del database.
  2. Installare il pacchetto zabbix-sql-scripts più recente compatibile con la propria versione di Zabbix (ad esempio, per RHEL: dnf install zabbix-sql-scripts).
  3. Eseguire gli script per il proprio database.
  4. Avviare Zabbix server.

Eseguire gli script solo per il database del server. Il proxy non trarrà beneficio da questo aggiornamento.

Se il database utilizza partizioni, contattare l'amministratore DB o il Supporto Zabbix per assistenza.

I file CSV possono essere rimossi dopo un aggiornamento riuscito alle chiavi primarie.

Facoltativamente, Zabbix frontend può essere impostato in modalità di manutenzione.

MySQL

L'esportazione e l'importazione devono essere eseguite in tmux/screen per garantire che la sessione non venga interrotta.

Vedi anche: Note importanti

MySQL 8.4+ con mysqlsh

Questo metodo può essere utilizzato con un server Zabbix in esecuzione, ma si consiglia di arrestare il server per la durata dell'aggiornamento. MySQL Shell (mysqlsh) deve essere installato e in grado di connettersi al DB.

  • Accedere alla console MySQL come root (consigliato) oppure come qualsiasi utente con privilegi FILE.

  • Avviare MySQL con la variabile local_infile abilitata.

  • Rinominare le vecchie tabelle e creare le nuove tabelle eseguendo history_upgrade_prepare.sql.

mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
  • Esportare e importare i dati.

Connettersi tramite mysqlsh. Se si utilizza una connessione socket, potrebbe essere necessario specificare il percorso.

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

Passare alla modalità JavaScript usando:

\js

Quindi eseguire il codice seguente (CSVPATH può essere modificato secondo necessità):

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" });

Se si riceve il messaggio "JavaScript is not supported", l'installazione di MySQL Shell non include il supporto JS. In tal caso, installare il pacchetto ufficiale MySQL Shell di Oracle (oppure compilarlo dai sorgenti) in modo che la modalità JavaScript sia abilitata.

MariaDB/MySQL 8.4+ senza mysqlsh

Questo metodo di aggiornamento richiede più tempo e deve essere utilizzato solo se non è possibile eseguire un aggiornamento con mysqlsh.

Aggiornamento delle tabelle
  • Accedere alla console MySQL come root (consigliato) o come qualsiasi utente con privilegi FILE.

  • Se si esegue la migrazione con un server Zabbix in esecuzione, avviare MySQL con la variabile local_infile abilitata.

  • Rinominare le vecchie tabelle e creare le nuove tabelle eseguendo history_upgrade_prepare.sql:

mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
Migrazione con server arrestato

max_execution_time (in MySQL) o max_statement_time (in MariaDB) deve essere disabilitato prima della migrazione dei dati per evitare timeout durante la migrazione.

Per MySQL:

SET @@max_execution_time=0;

Per 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;

Seguire le istruzioni post-migrazione per eliminare le vecchie tabelle.

Migrazione con server in esecuzione

Verificare per quali percorsi è abilitata l'importazione/esportazione:

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

Se il valore di secure_file_priv è un percorso a una directory, l'esportazione/importazione verrà eseguita per i file in quella directory.
In questo caso, modificare di conseguenza i percorsi dei file nelle query oppure impostare il valore di secure_file_priv su una stringa vuota per la durata dell'aggiornamento.

Se il valore di secure_file_priv è vuoto, l'esportazione/importazione può essere eseguita da qualsiasi posizione.

Se il valore di secure_file_priv è NULL, impostarlo sul percorso che contiene i dati della tabella esportata (/var/lib/mysql-files/ nell'esempio sopra).

Per ulteriori informazioni, vedere la documentazione MySQL o la documentazione MariaDB.

max_execution_time (in MySQL) o max_statement_time (in MariaDB) deve essere disabilitato prima dell'esportazione dei dati per evitare timeout durante l'esportazione.

Per MySQL:

SET @@max_execution_time=0;

Per 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';

Seguire le istruzioni post-migrazione per eliminare le vecchie tabelle.

PostgreSQL

L'esportazione e l'importazione devono essere eseguite in tmux/screen per garantire che la sessione non venga interrotta. Per le installazioni con TimescaleDB, saltare questa sezione e procedere a PostgreSQL + TimescaleDB.

Vedere anche: Note importanti

Aggiornamento delle tabelle

  • Rinominare le tabelle usando history_upgrade_prepare.sql:
sudo -u zabbix psql zabbix < /usr/share/zabbix/sql-scripts/postgresql/option-patches/history_upgrade_prepare.sql

Migrazione con server arrestato

  • Esportare la cronologia corrente, importarla nella tabella temporanea, quindi inserire i dati nelle nuove tabelle ignorando i duplicati:
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;

Vedere i suggerimenti per migliorare le prestazioni di INSERT: PostgreSQL: Bulk Loading Huge Amounts of Data, Checkpoint Distance and Amount of WAL.

Migrazione con server in esecuzione

  • Esporta la cronologia corrente, importala nella tabella temporanea, quindi inserisci i dati nelle nuove tabelle ignorando i duplicati:
\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

L'esportazione e l'importazione devono essere eseguite in tmux/screen per garantire che la sessione non venga interrotta. Il server Zabbix deve essere spento durante l'aggiornamento.

Vedi anche: Note importanti

  • Rinominare le tabelle utilizzando history_upgrade_prepare.sql.

    • Se la compressione è abilitata (nell'installazione predefinita), eseguire lo script da /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
    • Se la compressione è disabilitata, eseguire lo script da /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
  • Eseguire gli script di migrazione delle hypertable di TimescaleDB in base alle impostazioni di compressione:

    • Se la compressione è abilitata (nell'installazione predefinita), eseguire gli script da /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
    • Se la compressione è disabilitata, eseguire gli script da /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

Vedi anche: Suggerimenti per migliorare le prestazioni di INSERT.

Post-migrazione

Per tutti i database, una volta completata la migrazione, procedere come segue:

  • Verificare che tutto funzioni come previsto.

  • Eliminare le vecchie tabelle:

DROP TABLE history_old;
DROP TABLE history_uint_old;
DROP TABLE history_str_old;
DROP TABLE history_log_old;
DROP TABLE history_text_old;
  • Per TimescaleDB, eliminare anche la seguente vecchia tabella:
DROP TABLE trends_old;

Vedi anche