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

Обзор

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

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

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

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

Автоматическое обновление базы данных до первичных ключей не предусмотрено; однако существующие установки можно обновить вручную после обновления сервера Zabbix до версии 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.4+ с 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.4+ без 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

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

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

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

  • Переименуйте таблицы с помощью 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

См. также: Советы по повышению производительности 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;

См. также