Zabbix大规模数据库分区的核心目标是按时间切片管理历史数据,提升查询与清理效率,适用于监控主机超200台、history_uint表达数十GB的场景;需优先对history、history_uint等6张历史表按clock字段做RANGE月分区,并停用Housekeeper。

搭建 Zabbix 大规模数据库分区,核心目标是把历史数据按时间切片管理,让查询只扫描相关分区、删除只操作整个分区(而非逐行扫描),从而显著提升查询速度和清理效率。这不是“加功能”,而是重构数据组织方式,尤其适用于监控主机超 200 台、运行超半年、history_uint 表达数十 GB 的场景。
明确分区范围和表选择
Zabbix 中真正影响性能的主要是历史类大表,不是所有表都需要分区。优先处理以下 6 张表:
- history(浮点型历史值)
- history_uint(无符号整型历史值)
- history_str(字符串型历史值)
- history_text(文本型历史值)
- history_log(日志型历史值)
- trends 和 trends_uint(聚合趋势数据)
注意:events、alerts 等配置或事件表不建议分区;items、hosts 等元数据表更无需分区。分区只针对按时间增长、体积膨胀快、查询常带 clock 条件的表。
停服 + 备份 + 修改表结构
分区必须在低峰期操作,且全程不可逆,务必严格按顺序执行:
- 停止 Zabbix Server:防止写入冲突,命令为
systemctl stop zabbix-server - 全库逻辑备份(推荐):
mysqldump -u zabbix -p --single-transaction zabbix > zabbix_full_backup.sql - 对目标表重建主键与索引(Zabbix 4.0+ 可跳过,但 3.x 必须执行):
ALTER TABLE history_uint DROP PRIMARY KEY, ADD INDEX (id), DROP INDEX history_uint_2, ADD INDEX history_uint_2 (itemid, clock);
目的是避免分区后因主键含clock导致 DML 报错
按月 RANGE 分区并自动维护
使用 RANGE 按 clock 字段(Unix 时间戳)分区最稳妥。例如为 history_uint 创建未来 12 个月分区:
ALTER TABLE history_uint PARTITION BY RANGE (clock) (
PARTITION p202507 VALUES LESS THAN (UNIX_TIMESTAMP('2025-08-01')),
PARTITION p202508 VALUES LESS THAN (UNIX_TIMESTAMP('2025-09-01')),
...
PARTITION p202606 VALUES LESS THAN (UNIX_TIMESTAMP('2026-07-01'))
);
后续需用定时任务(如每天凌晨)自动添加新分区、删除过期分区。可用 Perl 或存储过程实现,但推荐 Perl 脚本(更易调试、故障时不影响 MySQL 内核):
- 脚本读取当前时间,生成下月分区 SQL
- 检查是否存在该分区,避免重复创建
- 同时执行
ALTER TABLE ... DROP PARTITION p202507清理最早分区(等价于秒级删光整月数据)
配套关闭 Housekeeper 并调优参数
启用分区后,Zabbix 自带的 Housekeeper 就该停用了——它逐行删数据,与分区“整块清理”理念冲突,还会拖慢数据库。
- 编辑
/etc/zabbix/zabbix_server.conf,设:HousekeepingFrequency=0(禁用自动清理)MaxHousekeeperDelete=0 - 保留 Zabbix 前端中“历史数据保留天数”设置(如 90 天),仅作策略参考,实际清理由分区脚本控制
- 确认 MySQL 已启用
innodb_file_per_table=1,便于单个分区文件独立管理与收缩
分区不是一劳永逸,需配合定期检查 information_schema.partitions 确认分区数量与时间范围是否连续,避免出现“空档期”或“重叠分区”。

















