某些数据库(例如,MySQL)要求分区列必须是表的唯一约束的一部分。 因此,为了按时间对 auditlog
表进行分区,必须将主键从 auditid
更改为复合键 auditid
+ clock
。
本节提供了更改 auditlog
表主键的说明。
本页提供的说明适用于高级用户。 请注意,这些说明可能需要根据您的特定配置进行调整。 修改主键可能与未来的升级补丁不兼容,因此可能需要手动处理未来的升级。
修改主键可能是一项资源消耗较大的操作,所需时间取决于 auditlog
表的大小。 建议在修改期间停止 Zabbix server 并将 Zabbix 前端切换到 maintenance mode。 但是,如果确实必要,也可以在不停机的情况下修改主键(见下文)。
对 auditlog
表进行分区可以改善例如在大型环境中的 housekeeping 操作。
尽管 Zabbix housekeeping 当前还无法利用分区表(TimescaleDB 除外),但您可以禁用 Zabbix 的 housekeeping 功能,并通过脚本管理 delete 分区。
自 Zabbix 7.0 开始,用于 TimescaleDB 的 auditlog
表已转换为 hypertable,这使得 housekeeper 可以按数据块来删除数据。
要将现有的 auditlog
表升级为 hypertable,请参阅 升级timescaledb架构。
MySQL在执行ALTER TABLE
操作期间会自动重建主键索引。
但是,建议同时使用OPTIMIZE TABLE
语句手动重建索引,以确保数据库性能处于最佳状态。
重建索引可能会临时占用与表本身大小相当的额外磁盘空间。
要获取当前数据和索引的大小,可以execute执行以下语句:
如果磁盘可用空间不足,请按照无停机时间修改主键的说明进行操作。
还有其他选项可供选择:
sort_buffer_size
MySQL参数可能有助于手动重建索引时减少磁盘空间的使用。1。删除当前的 auditlog
表主键并添加新的主键。
2。重建索引(可选但强烈建议,参见 有关重建索引的重要说明)。
修改主键的手动方法在此处描述。 另外,您可以使用 Percona 提供的 pt-online-schema-change 工具包。 该工具包可以自动执行以下操作,同时最小化用于修改 auditlog
表所需的空间。
1. 创建一个具有新主键和 create 索引的新表。
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. 删除旧表。
在 ALTER TABLE
操作期间,PostgreSQL 会自动重建主键的索引。
但是,建议同时使用 REINDEX TABLE CONCURRENTLY
语句手动重建索引,以确保数据库性能处于最佳状态。
重建索引可能会暂时需要多达当前索引所占用磁盘空间三倍的存储空间。
要获取索引的当前大小,您可以 execute 以下 query:
如果可用磁盘空间有限,可参考 Altering primary key without downtime 中的说明进行操作。
此外,还有其他可选方案:
maintenance_work_mem
可能有助于手动重建索引时减少磁盘空间的使用。temp_tablespaces
,以指定一个不同的表空间用于临时 objects。1。删除当前的 auditlog
表主键并添加新的主键。
ALTER TABLE auditlog DROP CONSTRAINT auditlog_pkey;
ALTER TABLE auditlog ADD PRIMARY KEY (auditid,clock);
2。重建索引(可选但强烈建议,请参阅 有关重建索引的重要说明)。
手动修改主键的方法在此处描述。
或者,可以考虑使用 pg_repack
扩展来创建新表、复制数据以及交换表。
1. 创建具有新主键和 create 索引的新表。
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. 删除旧表。
Oracle 在执行 ALTER TABLE
操作期间会自动重建主键的索引。
但是,建议同时使用 ALTER INDEX <index> REBUILD PARALLEL
语句手动重建索引,以确保数据库性能最优。
重建索引可能会临时占用大量磁盘空间。
如果磁盘空间有限,请参考 Altering primary key without downtime 的说明进行操作。
此外还可以考虑以下选项:
SORT_AREA_SIZE
Oracle 参数可能有助于在手动重建索引时减少磁盘空间的使用。ALTER INDEX auditlog_1 REBUILD PARALLEL 4
1。获取约束名称。
SELECT CONSTRAINT_NAME FROM all_constraints WHERE TABLE_NAME = 'AUDITLOG' AND CONSTRAINT_TYPE = 'P';
2。删除当前的 auditlog
表主键并添加新的主键。
ALTER TABLE auditlog DROP CONSTRAINT <constraint_name>;
ALTER TABLE auditlog ADD CONSTRAINT auditlog_pk PRIMARY KEY (auditid, clock);
3。重建索引(可选但强烈推荐,请参阅 [有关重建索引的重要说明](#important-notes-on-rebuilding-indexes-2)。
3.1。获取索引名称。
3.2。重建每个索引。
ALTER INDEX auditlog_pk REBUILD PARALLEL;
ALTER INDEX auditlog_1 REBUILD PARALLEL;
ALTER INDEX auditlog_2 REBUILD PARALLEL;
ALTER INDEX auditlog_3 REBUILD PARALLEL;
1。使用新的主键和create索引创建一个新表。
CREATE TABLE auditlog_new (
auditid nvarchar2(25) ,
userid number(20) NULL,
username nvarchar2(100) DEFAULT '' ,
clock number(10) DEFAULT '0' NOT NULL,
ip nvarchar2(39) DEFAULT '' ,
action number(10) DEFAULT '0' NOT NULL,
resourcetype number(10) DEFAULT '0' NOT NULL,
resourceid number(20) NULL,
resource_cuid nvarchar2(25) ,
resourcename nvarchar2(255) DEFAULT '' ,
recordsetid nvarchar2(25) ,
details nclob DEFAULT '' ,
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。删除旧表。