4 准备用于分区的审计日志表

概述

某些数据库(例如 MySQL)要求分区列成为表的唯一约束的一部分。因此,auditlog要按时间对表进行分区,必须将主键从 更改auditid为 复合键auditid + clock

本节提供更改 auditlog 表主键的指导说明。

本页提供的说明适用于高级用户。请注意,这些说明可能需要根据您的具体配置进行调整。更改主键也可能与将来的升级补丁不兼容,因此可能需要手动处理将来的升级。更改主键可能

是一项资源密集型操作,根据表大小需要花费大量时间auditlog。建议在更改时停止 Zabbix Server并将 Zabbix 前端切换到[维护模式manual/web_interface/maintenance_mode)。但是,如果绝对必要,有一种方法可以在不停机的情况下更改主键(见下文)。

auditlog例如,对表进行分区可以改善大型设置中的内务管理。尽管 Zabbix内务管理目前无法利用分区表(TimescaleDB 除外),但您可以使用脚本禁用 Zabbix 内务管理并删除分区。

自 Zabbix 7.0 起,auditlogTimescaleDB 的表已转换为超表,允许管家按块删除数据。要将现有auditlog表升级为超表,请postgresql/timescaledb/schema.sql在启动 Zabbix server之前重新运行该脚本。如果在未先运行此脚本的情况下启动 Zabbix server,则 Zabbix server将记录警告。另请参阅:TimescaleDB 安装

MySQL

关于重建索引的重要说明

MySQL 会在操作过程中自动重建主键的索引ALTER TABLE。但是,强烈建议使用该 OPTIMIZE TABLE语句手动重建索引,以确保最佳数据库性能。

重建索引可能暂时需要与表本身一样多的额外磁盘空间。要获取数据和索引的当前大小,可以执行以下语句:

  1. ANALYZE TABLE auditlog;
  2. SHOW TABLE STATUS LIKE 'auditlog';

如果担心可用磁盘空间,请按照在不停机的情况下更改主键 的说明进行操作。还有其他选项可用:

  • 增加sort_buffer_sizeMySQL 参数可能有助于在手动重建索引时减少磁盘空间使用量。但是,修改此变量可能会影响数据库的整体内存使用量。
  • 考虑通过删除可能不必要的数据来释放空间。
  • 在执行内存管家之前,请考虑减少数据存储期 管家参数。
停机期间更改主键

1. 删​​除当前auditlog表主键并添加新的主键。

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

2. 重建索引(可选但强烈推荐,请参阅有关重建索引的重要说明)。

  1. OPTIMIZE TABLE auditlog;
无需停机即可修改主键

此处介绍了手动更改主键的方法。或者,您可以使用Percona 的pt-online-schema-change工具包。此工具包会自动执行以下操作,同时最大限度地减少用于更改auditlog表的空间。

1. 使用新的主键创建新表并创建索引。

  1. CREATE TABLE `auditlog_new` (
  2. `auditid` varchar(25) NOT NULL,
  3. `userid` bigint unsigned NULL,
  4. `username` varchar(100) DEFAULT '' NOT NULL,
  5. `clock` integer DEFAULT '0' NOT NULL,
  6. `ip` varchar(39) DEFAULT '' NOT NULL,
  7. `action` integer DEFAULT '0' NOT NULL,
  8. `resourcetype` integer DEFAULT '0' NOT NULL,
  9. `resourceid` bigint unsigned NULL,
  10. `resource_cuid` varchar(25) NULL,
  11. `resourcename` varchar(255) DEFAULT '' NOT NULL,
  12. `recordsetid` varchar(25) NOT NULL,
  13. `details` longtext NOT NULL,
  14. PRIMARY KEY (auditid,clock)
  15. ) ENGINE=InnoDB;
  16. CREATE INDEX `auditlog_1` ON `auditlog_new` (`userid`,`clock`);
  17. CREATE INDEX `auditlog_2` ON `auditlog_new` (`clock`);
  18. CREATE INDEX `auditlog_3` ON `auditlog_new` (`resourcetype`,`resourceid`);

2. 交换表.

  1. RENAME TABLE auditlog TO auditlog_old, auditlog_new TO auditlog;

3. 将数据从旧表复制到新表。

  1. INSERT INTO auditlog SELECT * FROM auditlog_old;

这可以分块完成(根据需要使用INSERT INTO带有子句的多个语句),以避免过度使用资源。WHERE clock

4. 删除旧表。

  1. DROP TABLE auditlog_old;

PostgreSQL

关于重建索引的重要说明

会在操作过程中自动重建主键的索引ALTER TABLE。但是,强烈建议使用该REINDEX TABLE CONCURRENTLY语句手动重建索引,以确保最佳数据库性能。

重建索引可能暂时需要最多三倍于索引当前所用磁盘空间。要获取索引的当前大小,可以执行以下查询:

  1. SELECT pg_size_pretty(pg_indexes_size('auditlog'));

如果担心可用磁盘空间,请按照[在不停机的情况下更改主键](#altering-primary-key-without-downtime-1的说明进行操作。还有其他选项可用:

  • 增加maintenance_work_memPostgreSQL 参数可能有助于在手动重建索引时减少磁盘空间使用量。但是,修改此变量可能会影响数据库的整体内存使用量。
  • 如果您有其他具有更多可用空间的磁盘或表空间,您可以考虑更改索引重建的临时存储位置。temp_tablespaces 参数来为临时对象指定不同的表空间。
  • 考虑通过删除可能不必要的数据来释放空间。
  • 在执行内存管家之前,请考虑减少数据存储期 管家参数。
停机期间更改主键

1. 删​​除当前auditlog 表主键并添加新的主键。

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

2.重建索引(可选但强烈推荐,请参阅有关重建索引的重要说明)。

  1. REINDEX TABLE CONCURRENTLY auditlog;
无需停机即可修改主键

这里描述了手动修改主键的方法。或者,pg_repack可以考虑使用扩展来创建新表、复制数据和交换表。

1. 使用新的主键创建新表并创建索引。

  1. CREATE TABLE auditlog_new (
  2. auditid varchar(25) NOT NULL,
  3. userid bigint NULL,
  4. username varchar(100) DEFAULT '' NOT NULL,
  5. clock integer DEFAULT '0' NOT NULL,
  6. ip varchar(39) DEFAULT '' NOT NULL,
  7. action integer DEFAULT '0' NOT NULL,
  8. resourcetype integer DEFAULT '0' NOT NULL,
  9. resourceid bigint NULL,
  10. resource_cuid varchar(25) NULL,
  11. resourcename varchar(255) DEFAULT '' NOT NULL,
  12. recordsetid varchar(25) NOT NULL,
  13. details text DEFAULT '' NOT NULL,
  14. PRIMARY KEY (auditid,clock)
  15. );
  16. CREATE INDEX auditlog_new_1 ON auditlog_new (userid,clock);
  17. CREATE INDEX auditlog_new_2 ON auditlog_new (clock);
  18. CREATE INDEX auditlog_new_3 ON auditlog_new (resourcetype,resourceid);

2. 交换表。

  1. ALTER TABLE auditlog RENAME TO auditlog_old;
  2. ALTER TABLE auditlog_new RENAME TO auditlog;

3.将数据从旧表复制到新表。

  1. INSERT INTO auditlog SELECT * FROM auditlog_old;

usage.这可以分块完成(根据需要使用INSERT INTO 带有子句的多个语句WHERE clock),以避免过度使用资源。

4. 删除旧表。

  1. DROP TABLE auditlog_old;

Oracle

关于重建索引的重要说明

Oracle 会在操作过程中自动重建主键的索引ALTER TABLE。但是,强烈建议您使用语句手动重建索引,ALTER INDEX <index> REBUILD PARALLEL 以确保最佳数据库性能。

重建索引可能暂时需要大量磁盘空间。

如果担心可用磁盘空间,请按照在不停机的情况下更改主键的说明 进行操作。还有其他选项可用:

  • 增加SORT_AREA_SIZEOracle 参数可能有助于在手动重建索引时减少磁盘空间使用量。但是,修改此变量会影响数据库的整体内存使用量。
  • 您可以使用 PARALLEL 子句设置并行度,例如:ALTER INDEX auditlog_1 REBUILD PARALLEL 4
  • 考虑通过删除可能不必要的数据来释放空间。
  • 在执行管家之前,请考虑减少数据存储期 管家参数。
停机期间更改主键

1. 检索约束名称。

  1. SELECT CONSTRAINT_NAME FROM all_constraints WHERE TABLE_NAME = 'AUDITLOG' AND CONSTRAINT_TYPE = 'P';

2. 删除当前auditlog表主键并添加新的主键。

  1. ALTER TABLE auditlog DROP CONSTRAINT <constraint_name>;
  2. ALTER TABLE auditlog ADD CONSTRAINT auditlog_pk PRIMARY KEY (auditid, clock);

3. 重建索引(可选但强烈推荐,请参阅有关重建索引的重要说明)。

3.1. 获取索引名称。

  1. SELECT index_name FROM user_indexes WHERE table_name='AUDITLOG';

3.2. 重建各个索引。

  1. ALTER INDEX auditlog_pk REBUILD PARALLEL;
  2. ALTER INDEX auditlog_1 REBUILD PARALLEL;
  3. ALTER INDEX auditlog_2 REBUILD PARALLEL;
  4. ALTER INDEX auditlog_3 REBUILD PARALLEL;
无需停机即可修改主键

1. 使用新的主键创建新表并创建索引。

  1. CREATE TABLE auditlog_new (
  2. auditid nvarchar2(25) ,
  3. userid number(20) NULL,
  4. username nvarchar2(100) DEFAULT '' ,
  5. clock number(10) DEFAULT '0' NOT NULL,
  6. ip nvarchar2(39) DEFAULT '' ,
  7. action number(10) DEFAULT '0' NOT NULL,
  8. resourcetype number(10) DEFAULT '0' NOT NULL,
  9. resourceid number(20) NULL,
  10. resource_cuid nvarchar2(25) ,
  11. resourcename nvarchar2(255) DEFAULT '' ,
  12. recordsetid nvarchar2(25) ,
  13. details nclob DEFAULT '' ,
  14. PRIMARY KEY (auditid,clock)
  15. );
  16. CREATE INDEX auditlog_new_1 ON auditlog_new (userid,clock);
  17. CREATE INDEX auditlog_new_2 ON auditlog_new (clock);
  18. CREATE INDEX auditlog_new_3 ON auditlog_new (resourcetype,resourceid);

2. 交换表.

  1. ALTER TABLE auditlog RENAME TO auditlog_old;
  2. ALTER TABLE auditlog_new RENAME TO auditlog;

3. 将数据从旧表复制到新表。

  1. INSERT INTO auditlog SELECT * FROM auditlog_old;

这可以分块完成(根据需要使用INSERT INTO带有子句的多个语句),以避免过度使用资源。WHERE clock

4. 删除旧表。

  1. DROP TABLE auditlog_old;

另请参阅