You are viewing documentation for the development version, it may be incomplete.
Join our translation project and help translate Zabbix documentation into your native language.

4 監査ログテーブルのパーティション化の準備

概要

一部のデータベース(例えば、MySQL)では、パーティション分割カラムがテーブルの一意制約の一部である必要があります。 そのため、auditlogテーブルを時間でパーティション分割するには、主キーをauditidから複合キーauditid + clockに変更する必要があります。

このセクションでは、auditlogテーブルの主キーを変更する手順について説明します。

このページで提供されている手順は、上級ユーザー向けに設計されています。 これらの手順は、お使いの構成に合わせて調整が必要な場合がありますのでご注意ください。 主キーの変更は、将来のアップグレードパッチと互換性がない場合もあるため、将来のアップグレードを手動で処理する必要があるかもしれません。

主キーの変更は、auditlogテーブルのサイズによっては多くのリソースを消費し、時間がかかる操作となる場合があります。 変更作業中はZabbixサーバーを停止し、Zabbixフロントエンドをメンテナンスモードに切り替えることを推奨します。 ただし、どうしても必要な場合は、ダウンタイムなしで主キーを変更する方法もあります(下記参照)。

auditlogテーブルのパーティショニングは、大規模なセットアップでのハウスキーピングなどを改善できます。 Zabbixのハウスキーピングは現在、(TimescaleDBを除き)パーティショニングされたテーブルを利用できませんが、Zabbixのハウスキーピングを無効にし、スクリプトを使用してパーティションを削除することができます。

Zabbix 7.0以降、TimescaleDB用のauditlogテーブルはハイパーテーブルに変換され、ハウスキーパーがチャンク単位でデータを削除できるようになりました。 既存のauditlogテーブルをハイパーテーブルにアップグレードするには、TimescaleDBスキーマのアップグレードを参照してください。

MySQL

インデックスの再構築に関する重要な注意事項

MySQLは、ALTER TABLE操作中に主キーのインデックスを自動的に再構築します。 ただし、最適なデータベースパフォーマンスを確保するために、OPTIMIZE TABLEステートメントで手動でインデックスを再構築することも強く推奨します。

インデックスの再構築には、一時的にテーブル自体が使用するのと同じくらいの追加ディスク容量が必要になる場合があります。 データとインデックスの現在のサイズを取得するには、次のステートメントを実行できます。

ANALYZE TABLE auditlog;
       SHOW TABLE STATUS LIKE 'auditlog';

利用可能なディスク容量が懸念される場合は、ダウンタイムなしで主キーを変更する手順に従ってください。 他にも次のような選択肢があります:

  • インデックスを手動で再構築する際のディスク使用量を減らすために、sort_buffer_size MySQLパラメータを増やすことが役立つ場合があります。 ただし、この変数を変更すると、データベース全体のメモリ使用量に影響を与える可能性があります。
  • 不要なデータを削除して空き容量を確保することを検討してください。
  • ハウスキーパーを実行する前に、データ保存期間 housekeeperパラメータを短くすることを検討してください。
ダウンタイムを伴う主キーの変更

1. 現在の auditlog テーブルの主キーを削除し、新しい主キーを追加します。

ALTER TABLE auditlog DROP PRIMARY KEY, ADD PRIMARY KEY (auditid, clock);

2. インデックスを再構築します(オプションですが強く推奨します。インデックス再構築に関する重要な注意事項を参照してください)。

OPTIMIZE TABLE auditlog;
ダウンタイムなしで主キーを変更する

主キーを手動で変更する方法について説明します。 または、Perconaのpt-online-schema-changeツールキットを使用することもできます。 このツールキットは、auditlogテーブルの変更に使用されるスペースを最小限に抑えながら、以下のアクションを自動的に実行します。

1. 新しい主キーで新しいテーブルを作成し、インデックスを作成します。

CREATE TABLE `auditlog_new` (
         `auditid`            varchar(25)                               NOT NULL,
         `userid`             bigint unsigned                           NULL,
         `username`           varchar(100)    DEFAULT ''                NOT NULL,
         `clock`              integer         DEFAULT '0'               NOT NULL,
         `ip`                 varchar(39)     DEFAULT ''                NOT NULL,
         `action`             integer         DEFAULT '0'               NOT NULL,
         `resourcetype`       integer         DEFAULT '0'               NOT NULL,
         `resourceid`         bigint unsigned                           NULL,
         `resource_cuid`      varchar(25)                               NULL,
         `resourcename`       varchar(255)    DEFAULT ''                NOT NULL,
         `recordsetid`        varchar(25)                               NOT NULL,
         `details`            longtext                                  NOT NULL,
         PRIMARY KEY (auditid,clock)
       ) ENGINE=InnoDB;
       CREATE INDEX `auditlog_1` ON `auditlog_new` (`userid`,`clock`);
       CREATE INDEX `auditlog_2` ON `auditlog_new` (`clock`);
       CREATE INDEX `auditlog_3` ON `auditlog_new` (`resourcetype`,`resourceid`);

2. テーブルを入れ替えます。

RENAME TABLE auditlog TO auditlog_old, auditlog_new TO auditlog;

3. 古いテーブルから新しいテーブルにデータをコピーします。

INSERT INTO auditlog SELECT * FROM auditlog_old;

リソースの過剰な使用を避けるために、必要に応じてWHERE clock句を使用した複数のINSERT INTOステートメントでチャンク単位で実行できます。

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

DROP TABLE auditlog_old;

PostgreSQL

インデックス再構築に関する重要な注意事項

PostgreSQLは、ALTER TABLE操作中に主キーのインデックスを自動的に再構築します。 ただし、最適なデータベースパフォーマンスを確保するために、REINDEX TABLE CONCURRENTLYステートメントを使用して手動でインデックスを再構築することを強く推奨します。

インデックスの再構築には、一時的に現在インデックスで使用されているディスク容量の最大3倍が必要になる場合があります。 現在のインデックスサイズを取得するには、次のクエリを実行できます。

SELECT pg_size_pretty(pg_indexes_size('auditlog'));

利用可能なディスク容量が懸念される場合は、ダウンタイムなしで主キーを変更する手順に従ってください。 他にも以下のようなオプションがあります:

  • インデックスを手動で再構築する際にディスク容量の使用量を減らすために、maintenance_work_mem PostgreSQLパラメータを増やすことが役立つ場合があります。 ただし、この変数を変更すると、データベース全体のメモリ使用量に影響を与える可能性があります。
  • より多くの空き容量がある別のディスクやテーブルスペースがある場合は、インデックス再構築時の一時的な保存場所を変更することを検討できます。 一時オブジェクト用の別のテーブルスペースを指定するには、temp_tablespaces PostgreSQLパラメータを設定できます。
  • 不要なデータを削除して空き容量を確保することを検討してください。
  • ハウスキーパーを実行する前に、データ保存期間 housekeeperパラメータを短くすることを検討してください。
ダウンタイムを伴う主キーの変更

1. 現在の auditlog テーブルの主キーを削除し、新しい主キーを追加します。

ALTER TABLE auditlog DROP CONSTRAINT auditlog_pkey;
       ALTER TABLE auditlog ADD PRIMARY KEY (auditid,clock);

2. インデックスを再構築します(オプションですが強く推奨します。インデックス再構築に関する重要な注意事項を参照してください)。

REINDEX TABLE CONCURRENTLY auditlog;
ダウンタイムなしで主キーを変更する

主キーを手動で変更する方法について説明します。 また、pg_repack拡張機能を使用して新しいテーブルを作成し、データをコピーしてテーブルを入れ替えることも検討できます。

1. 新しい主キーで新しいテーブルを作成し、インデックスを作成します。

CREATE TABLE auditlog_new (
         auditid              varchar(25)                               NOT NULL,
         userid               bigint                                    NULL,
         username             varchar(100)    DEFAULT ''                NOT NULL,
         clock                integer         DEFAULT '0'               NOT NULL,
         ip                   varchar(39)     DEFAULT ''                NOT NULL,
         action               integer         DEFAULT '0'               NOT NULL,
         resourcetype         integer         DEFAULT '0'               NOT NULL,
         resourceid           bigint                                    NULL,
         resource_cuid        varchar(25)                               NULL,
         resourcename         varchar(255)    DEFAULT ''                NOT NULL,
         recordsetid          varchar(25)                               NOT NULL,
         details              text            DEFAULT ''                NOT NULL,
         PRIMARY KEY (auditid,clock)
       );
       CREATE INDEX auditlog_new_1 ON auditlog_new (userid,clock);
       CREATE INDEX auditlog_new_2 ON auditlog_new (clock);
       CREATE INDEX auditlog_new_3 ON auditlog_new (resourcetype,resourceid);

2. テーブルを入れ替えます。

ALTER TABLE auditlog RENAME TO auditlog_old;
       ALTER TABLE auditlog_new RENAME TO auditlog;

3. 古いテーブルから新しいテーブルにデータをコピーします。

INSERT INTO auditlog SELECT * FROM auditlog_old;

リソースの過剰な使用を避けるために、必要に応じてWHERE clock句を使用した複数のINSERT INTO文で分割して実行することもできます。

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

DROP TABLE auditlog_old;

参考