3 プライマリキーへのデータベースのアップグレード

概要

このセクションでは、既存のインストールでテーブルを主キーに手動でアップグレードする手順を説明します。

主キーへのアップグレードは、データのインデックス化とアクセス方法を最適化し、クエリの高速化やスペースの節約につながる場合があります。 また、クラスタ構成でのデータ管理や同期を改善し、スケーリングを支援し、一部のサーバーが障害を起こしてもシステムの信頼性を維持します。

このページで提供されている手順は上級ユーザー向けに設計されており、特定の構成に合わせて調整が必要な場合があります。 主キーへのアップグレードは、時間とリソースを大量に消費する可能性があります。 十分な空きディスク容量があることを確認してください。データベースのサイズや保存されているデータによっては、履歴テーブルで現在使用されている容量の最大2.5倍のスペースが必要になる場合があります。

Zabbix 6.0以降の新規インストールでは、すべてのテーブルで主キーが使用されています。

主キーへの自動データベースアップグレードはありませんが、既存のインストールはZabbixサーバーを6.0以降にアップグレードした後に手動でアップグレードできます。

Zabbix 7.0以降、テーブルを主キーにアップグレードすると同時に、テーブルが倍精度データ型を使用するようにアップグレードされます。

Zabbix 7.0(またはそれ以降)をお使いの場合、テーブルはすでに倍精度を使用しています。 ただし、このページの手順に従って、すでに倍精度を使用しているテーブルに影響を与えることなく、テーブルを主キーにアップグレードすることができます。

Zabbix 6.4(またはそれ以前)をお使いの場合は、最初にテーブルを倍精度にアップグレードすることを検討してください。 詳細については、Zabbix 7.0ドキュメントの拡張範囲の数値値へのアップグレードを参照してください。

手順は以下のデータベース用に用意されています:

重要な注意事項

データベースのアップグレードを実行するには:

  1. Zabbixサーバーを停止します。

アップグレード中はZabbixサーバーを停止することを強く推奨します。 ただし、どうしても必要な場合は、サーバーが稼働している間にアップグレードを実行することもできます(MySQL、MariaDB、およびTimescaleDBなしのPostgreSQLのみ)。

  1. データベースのバックアップを取ります。
  2. Zabbixのバージョンに対応した最新のzabbix-sql-scriptsパッケージをインストールします(例:RHELの場合:dnf install zabbix-sql-scripts)。
  3. データベース用のスクリプトを実行します。
  4. Zabbixサーバーを起動します。

サーバーデータベースのみに対してスクリプトを実行してください。 プロキシにはこのアップグレードの恩恵はありません。

データベースでパーティションを使用している場合は、DB管理者またはZabbixサポートにお問い合わせください。

CSVファイルは、主キーへのアップグレードが正常に完了した後に削除できます。

オプションで、Zabbixフロントエンドをメンテナンスモードに切り替えることができます。

MySQL

セッションがドロップされないように、エクスポートとインポートは tmux/screen で実行する必要があります。

参照: 重要事項

MySQL 8.4+ と mysqlsh

この方法は稼働中の Zabbix サーバーでも使用できますが、アップグレード中はサーバーを停止することを推奨します。
MySQL Shell (mysqlsh) は インストール されており、DB に接続できる必要があります。

  • root(推奨)または FILE 権限を持つ任意のユーザーとして MySQL コンソールにログインします。

  • local_infile 変数を有効にして MySQL を起動します。

  • 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 サポートが含まれていません。
その場合は、Oracle から公式の MySQL Shell パッケージ をインストールするか(またはソースからビルドして)、JavaScript モードが有効になるようにしてください。

  • 古いテーブルを削除するには、移行後の手順 に従ってください。

MariaDB/MySQL 8.4+ で mysqlsh を使用しない場合

このアップグレード方法は時間がかかるため、mysqlsh を使用したアップグレードができない場合にのみ使用してください。

テーブルのアップグレード
  • MySQL コンソールに root(推奨)または FILE 権限を持つ任意のユーザーでログインします。

  • 稼働中の Zabbix サーバーで移行を行う場合は、local_infile 変数を有効にして MySQL を起動します。

  • 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 documentation または MariaDB documentation を参照してください。

データのエクスポート中のタイムアウトを避けるため、エクスポートの前に 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 サーバーを停止しておく必要があります。

See also: 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
  • 圧縮設定に基づいて TimescaleDB の hypertable 移行スクリプトを実行します:

    • 圧縮が有効な場合(デフォルトインストール)、/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

See also: INSERT パフォーマンスを改善するための Tips

移行後

すべてのデータベースで、移行が完了したら、次のことを行います。

  • すべてが期待通りに動作することを確認します。

  • 古いテーブルを削除します。

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;

こちらもご参照ください