3. Обновление базы данных для использования первичных ключей

Обзор

В этом разделе приведены инструкции по ручному обновлению таблиц в существующих установках до первичных ключей.

Переход на первичные ключи оптимизирует индексирование и доступ к данным, что может ускорить выполнение запросов и сэкономить место. Это также улучшает управление данными и синхронизацию в кластерных конфигурациях, помогая масштабированию и обеспечивая надежную работу системы даже при отказе некоторых серверов.

Инструкции, приведенные на этой странице, предназначены для опытных пользователей и могут потребовать адаптации под вашу конкретную конфигурацию. Переход на первичные ключи может быть длительным и ресурсоемким. Убедитесь, что доступно достаточно свободного места на диске; в зависимости от размера базы данных и хранимых данных процесс может потребовать до 2,5 раза больше места, чем сейчас занимают таблицы истории.

Первичные ключи используются для всех таблиц в новых установках начиная с Zabbix 6.0.

Автоматического обновления базы данных до первичных ключей нет; однако существующие установки можно обновить вручную после обновления Zabbix server до 6.0 или более новой версии.

Начиная с Zabbix 7.0, при обновлении таблиц до первичных ключей таблицы также переводятся на использование типов данных double precision.

Если у вас Zabbix 7.0 (или новее), таблицы уже используют double precision. Однако инструкции на этой странице по-прежнему можно использовать для обновления таблиц до первичных ключей без влияния на таблицы, которые уже используют double precision.

Если у вас Zabbix 6.4 (или более ранняя версия), рекомендуется сначала обновить таблицы до double precision. Дополнительную информацию см. в разделе Обновление до числовых значений расширенного диапазона в документации Zabbix 7.0.

Доступны инструкции для:

Важные примечания

Чтобы выполнить обновление базы данных:

  1. Остановите сервер Zabbix.

Настоятельно рекомендуется останавливать сервер Zabbix на время обновления. Однако, если это абсолютно необходимо, вы можете выполнить обновление, пока сервер работает (только для MySQL, MariaDB и PostgreSQL без TimescaleDB).

  1. Создайте резервную копию базы данных.
  2. Установите последнюю версию пакета zabbix-sql-scripts, совместимую с вашей версией Zabbix (например, для RHEL: dnf install zabbix-sql-scripts).
  3. Запустите скрипты для вашей базы данных.
  4. Запустите сервер Zabbix.

Запускайте скрипты только для базы данных сервера. Прокси не получит преимуществ от этого обновления.

Если база данных использует разделы, обратитесь за помощью к администратору БД или в службу поддержки Zabbix.

CSV-файлы можно удалить после успешного обновления до первичных ключей.

При необходимости веб-интерфейс Zabbix можно перевести в режим обслуживания.

MySQL

Экспорт и импорт необходимо выполнять в tmux/screen, чтобы гарантировать, что сеанс не будет прерван.

Смотрите также: Важные примечания

MySQL 8.0+ с mysqlsh

Этот метод можно использовать при работающем сервере Zabbix, но рекомендуется остановить сервер на время обновления. MySQL Shell (mysqlsh) должен быть установлен и иметь возможность подключаться к БД.

  • Войдите в консоль MySQL как root (рекомендуется) или как любой пользователь с привилегиями FILE.

  • Запустите MySQL с включенной переменной local_infile.

  • Переименуйте старые таблицы и создайте новые, выполнив history_upgrade_prepare.sql.

mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
  • Экспортируйте и импортируйте данные.

Подключитесь через mysqlsh. Если используется подключение через сокет, может потребоваться указать путь.

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

Переключитесь в режим JavaScript с помощью:

\js

Затем выполните приведенный ниже код (CSVPATH можно изменить при необходимости):

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

Если вы получите сообщение "JavaScript is not supported", значит в вашей установке MySQL Shell отсутствует поддержка JS. В этом случае установите официальный пакет MySQL Shell от Oracle (или соберите его из исходного кода), чтобы был включен режим JavaScript.

MariaDB/MySQL 8.0+ без mysqlsh

Этот способ обновления занимает больше времени и должен использоваться только в том случае, если обновление с помощью mysqlsh невозможно.

Обновление таблиц
  • Войдите в консоль MySQL как root (рекомендуется) или любой пользователь с привилегиями FILE.

  • Если выполняется миграция при работающем сервере Zabbix, запустите MySQL с включенной переменной local_infile.

  • Переименуйте старые таблицы и создайте новые, выполнив history_upgrade_prepare.sql:

mysql -uzabbix -p<password> zabbix < /usr/share/zabbix/sql-scripts/mysql/option-patches/history_upgrade_prepare.sql
Миграция при остановленном сервере

max_execution_time (в MySQL) или max_statement_time (в MariaDB) необходимо отключить перед миграцией данных, чтобы избежать тайм-аута во время миграции.

Для MySQL:

SET @@max_execution_time=0;

Для 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;

Следуйте инструкциям после миграции, чтобы удалить старые таблицы.

Миграция при работающем сервере

Проверьте, для каких путей включен импорт/экспорт:

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

Если значение secure_file_priv является путем к каталогу, экспорт/импорт будет выполняться для файлов в этом каталоге. В этом случае соответствующим образом измените пути к файлам в запросах или установите значение secure_file_priv в пустую строку на время обновления.

Если значение secure_file_priv пустое, экспорт/импорт можно выполнять из любого расположения.

Если значение secure_file_priv равно NULL, задайте путь к каталогу, который содержит экспортированные данные таблиц (в примере выше это '/var/lib/mysql-files/').

Дополнительную информацию см. в документации MySQL или документации MariaDB.

max_execution_time (в MySQL) или max_statement_time (в MariaDB) необходимо отключить перед экспортом данных, чтобы избежать тайм-аута во время экспорта.

Для MySQL:

SET @@max_execution_time=0;

Для 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';

Следуйте инструкциям после миграции, чтобы удалить старые таблицы.

PostgreSQL

Экспорт и импорт необходимо выполнять в tmux/screen, чтобы сеанс не был разорван. Для установок с TimescaleDB пропустите этот раздел и перейдите к PostgreSQL + TimescaleDB.

См. также: Важные примечания

Обновление таблиц

  • Переименуйте таблицы с помощью history_upgrade_prepare.sql:
sudo -u zabbix psql zabbix < /usr/share/zabbix/sql-scripts/postgresql/option-patches/history_upgrade_prepare.sql

Миграция с остановленным сервером

  • Экспортируйте текущую историю, импортируйте ее во временную таблицу, затем вставьте данные в новые таблицы, игнорируя дубликаты:
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;

См. советы по повышению производительности INSERT: PostgreSQL: Bulk Loading Huge Amounts of Data, Checkpoint Distance and Amount of WAL.

Миграция при работающем сервере

  • Экспортируйте текущую историю, импортируйте ее во временную таблицу, затем вставьте данные в новые таблицы, игнорируя дубликаты:
\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

Экспорт и импорт необходимо выполнять в tmux/screen, чтобы сеанс не был разорван. Во время обновления сервер Zabbix должен быть остановлен.

См. также: Important notes

  • Переименуйте таблицы с помощью history_upgrade_prepare.sql.

    • Если сжатие включено (в стандартной установке), выполните скрипт из /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
    • Если сжатие отключено, выполните скрипт из /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
  • Запустите скрипты миграции hypertable TimescaleDB в зависимости от настроек сжатия:

    • Если сжатие включено (в стандартной установке), выполните скрипты из /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
    • Если сжатие отключено, выполните скрипты из /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

См. также: Tips для повышения производительности INSERT.

Пост-миграция

Для всех баз данных после завершения миграции сделайте следующее:

  • Проверьте, что всё работает, как ожидается.

  • Удалите старые таблицы:

DROP TABLE history_old;
DROP TABLE history_uint_old;
DROP TABLE history_str_old;
DROP TABLE history_log_old;
DROP TABLE history_text_old;
  • Для TimescaleDB также удалите следующую старую таблицу:
DROP TABLE trends_old;

Смотрите также