一部のデータベース(例えば、MySQL)では、パーティション分割カラムがテーブルの一意制約の一部である必要があります。 そのため、auditlogテーブルを時間でパーティション分割するには、主キーをauditidから複合キーauditid + clockに変更する必要があります。
このセクションでは、auditlogテーブルの主キーを変更する手順について説明します。
このページで提供されている手順は、上級ユーザー向けに設計されています。 これらの手順は、お使いの構成に合わせて調整が必要な場合がありますのでご注意ください。 主キーの変更は、将来のアップグレードパッチと互換性がない場合もあるため、将来のアップグレードを手動で処理する必要があるかもしれません。
主キーの変更は、auditlogテーブルのサイズによっては多くのリソースを消費し、時間がかかる操作となる場合があります。 変更作業中はZabbixサーバーを停止し、Zabbixフロントエンドをメンテナンスモードに切り替えることを推奨します。 ただし、どうしても必要な場合は、ダウンタイムなしで主キーを変更する方法もあります(下記参照)。
auditlogテーブルのパーティショニングは、大規模なセットアップでのハウスキーピングなどを改善できます。 Zabbixのハウスキーピングは現在、(TimescaleDBを除き)パーティショニングされたテーブルを利用できませんが、Zabbixのハウスキーピングを無効にし、スクリプトを使用してパーティションを削除することができます。
Zabbix 7.0以降、TimescaleDB用のauditlogテーブルはハイパーテーブルに変換され、ハウスキーパーがチャンク単位でデータを削除できるようになりました。 既存のauditlogテーブルをハイパーテーブルにアップグレードするには、TimescaleDBスキーマのアップグレードを参照してください。
MySQLは、ALTER TABLE操作中に主キーのインデックスを自動的に再構築します。 ただし、最適なデータベースパフォーマンスを確保するために、OPTIMIZE TABLEステートメントで手動でインデックスを再構築することも強く推奨します。
インデックスの再構築には、一時的にテーブル自体が使用するのと同じくらいの追加ディスク容量が必要になる場合があります。 データとインデックスの現在のサイズを取得するには、次のステートメントを実行できます。
利用可能なディスク容量が懸念される場合は、ダウンタイムなしで主キーを変更する手順に従ってください。 他にも次のような選択肢があります:
sort_buffer_size MySQLパラメータを増やすことが役立つ場合があります。 ただし、この変数を変更すると、データベース全体のメモリ使用量に影響を与える可能性があります。1. 現在の auditlog テーブルの主キーを削除し、新しい主キーを追加します。
2. インデックスを再構築します(オプションですが強く推奨します。インデックス再構築に関する重要な注意事項を参照してください)。
主キーを手動で変更する方法について説明します。 または、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. テーブルを入れ替えます。
3. 古いテーブルから新しいテーブルにデータをコピーします。
リソースの過剰な使用を避けるために、必要に応じてWHERE clock句を使用した複数のINSERT INTOステートメントでチャンク単位で実行できます。
4. 古いテーブルを削除します。
PostgreSQLは、ALTER TABLE操作中に主キーのインデックスを自動的に再構築します。 ただし、最適なデータベースパフォーマンスを確保するために、REINDEX TABLE CONCURRENTLYステートメントを使用して手動でインデックスを再構築することを強く推奨します。
インデックスの再構築には、一時的に現在インデックスで使用されているディスク容量の最大3倍が必要になる場合があります。 現在のインデックスサイズを取得するには、次のクエリを実行できます。
利用可能なディスク容量が懸念される場合は、ダウンタイムなしで主キーを変更する手順に従ってください。 他にも以下のようなオプションがあります:
maintenance_work_mem PostgreSQLパラメータを増やすことが役立つ場合があります。 ただし、この変数を変更すると、データベース全体のメモリ使用量に影響を与える可能性があります。temp_tablespaces PostgreSQLパラメータを設定できます。1. 現在の auditlog テーブルの主キーを削除し、新しい主キーを追加します。
ALTER TABLE auditlog DROP CONSTRAINT auditlog_pkey;
ALTER TABLE auditlog ADD PRIMARY KEY (auditid,clock);2. インデックスを再構築します(オプションですが強く推奨します。インデックス再構築に関する重要な注意事項を参照してください)。
主キーを手動で変更する方法について説明します。 また、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. テーブルを入れ替えます。
3. 古いテーブルから新しいテーブルにデータをコピーします。
リソースの過剰な使用を避けるために、必要に応じてWHERE clock句を使用した複数のINSERT INTO文で分割して実行することもできます。
4. 古いテーブルを削除します。