Zabbix 数据库分区管理完整文档
📋 目录
概述
系统rocky9.8
数据库:mysql
生产环境中,为了解决zabbix时间久了卡顿问题,故分表,存储过程自动维护。
为什么要分区
- Zabbix 的
history_*和trends_*表会持续增长 - 单表数据量过大会导致查询性能下降
- 按时间分区可实现快速删除旧数据(DROP PARTITION 秒级完成)
分区策略
| 表名 | 分区方式 | 保留时间 | 预计大小 |
|---|---|---|---|
history |
按天 | 30 天 | ~2 GB |
history_bin |
按天 | 30 天 | <1 MB |
history_log |
按天 | 30 天 | <1 MB |
history_str |
按天 | 30 天 | ~15 MB |
history_text |
按天 | 30 天 | ~50 MB |
history_uint |
按天 | 30 天 | ~30 GB |
trends |
按月 | 12 个月 | ~15 MB |
trends_uint |
按月 | 12 个月 | ~400 MB |
自动化流程
每天凌晨 02:00
│
▼
┌─────────────────────────────┐
│ auto_add_daily_partitions() │
└─────────────────────────────┘
│
├── 删除 30 天前 history 分区
├── 删除 12 个月前 trends 分区
├── 创建今天 history 分区
└── 创建下个月 trends 分区
text
环境要求
系统要求
- MariaDB 10.0+ 或 MySQL 5.6+
- 磁盘空间:预留 50GB 以上
- MySQL Event Scheduler 已开启
检查清单
bash
# 1. 查看 MariaDB 版本
mysql -uroot -p -e "SELECT VERSION();"
# 2. 确认分区支持
mysql -uroot -p -e "SHOW PLUGINS;" | grep partition
# 3. 检查 Event Scheduler
mysql -uroot -p -e "SHOW VARIABLES LIKE 'event_scheduler';"
# 4. 检查磁盘空间
df -h /var/lib/mysql
# 5. 检查当前数据库大小
du -sh /var/lib/mysql/zabbix/
分表方案设计
分区命名规则
类型 命名格式 示例 含义
按天 pYYYYMMDD p20260611 2026年6月11日
按月 pYYYYMM p202606 2026年6月
分区边界说明
按天分区示例:
sql
PARTITION p20260611 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-12'))
存储 clock < 2026-06-12 00:00:00 的数据
即 2026年6月11日 全天的数据
按月分区示例:
sql
PARTITION p202606 VALUES LESS THAN (UNIX_TIMESTAMP('2026-07-01'))
存储 clock < 2026-07-01 00:00:00 的数据
即 2026年6月 全月的数据
操作步骤
第一步:备份数据库(重要!)
bash
# 全量备份
mysqldump -uroot -p --single-transaction --routines --triggers --events zabbix \
> zabbix_backup_$(date +%Y%m%d).sql
# 确认备份文件
ls -lh zabbix_backup_*.sql
第二步:改造表为分区表
注意:如果表已有数据,建议在维护窗口操作。新装环境可直接执行。
以下日期以 2026-06-11 为例,请根据实际日期调整分区日期。
sql
-- 登录 MySQL
mysql -uroot -p zabbix
执行以下 SQL(一次性复制执行):
sql
-- ============================================
-- 改造 history_uint 为按天分区表
-- ============================================
ALTER TABLE history_uint PARTITION BY RANGE (clock) (
PARTITION p20260611 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-12')),
PARTITION p20260612 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-13')),
PARTITION p20260613 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-14')),
PARTITION p20260614 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-15')),
PARTITION p20260615 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-16')),
PARTITION p20260616 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-17')),
PARTITION p20260617 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-18'))
);
-- ============================================
-- 改造 history
-- ============================================
ALTER TABLE history PARTITION BY RANGE (clock) (
PARTITION p20260611 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-12')),
PARTITION p20260612 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-13')),
PARTITION p20260613 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-14')),
PARTITION p20260614 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-15')),
PARTITION p20260615 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-16')),
PARTITION p20260616 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-17')),
PARTITION p20260617 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-18'))
);
-- ============================================
-- 改造 history_bin
-- ============================================
ALTER TABLE history_bin PARTITION BY RANGE (clock) (
PARTITION p20260611 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-12')),
PARTITION p20260612 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-13')),
PARTITION p20260613 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-14')),
PARTITION p20260614 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-15')),
PARTITION p20260615 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-16')),
PARTITION p20260616 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-17')),
PARTITION p20260617 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-18'))
);
-- ============================================
-- 改造 history_log
-- ============================================
ALTER TABLE history_log PARTITION BY RANGE (clock) (
PARTITION p20260611 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-12')),
PARTITION p20260612 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-13')),
PARTITION p20260613 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-14')),
PARTITION p20260614 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-15')),
PARTITION p20260615 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-16')),
PARTITION p20260616 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-17')),
PARTITION p20260617 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-18'))
);
-- ============================================
-- 改造 history_str
-- ============================================
ALTER TABLE history_str PARTITION BY RANGE (clock) (
PARTITION p20260611 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-12')),
PARTITION p20260612 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-13')),
PARTITION p20260613 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-14')),
PARTITION p20260614 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-15')),
PARTITION p20260615 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-16')),
PARTITION p20260616 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-17')),
PARTITION p20260617 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-18'))
);
-- ============================================
-- 改造 history_text
-- ============================================
ALTER TABLE history_text PARTITION BY RANGE (clock) (
PARTITION p20260611 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-12')),
PARTITION p20260612 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-13')),
PARTITION p20260613 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-14')),
PARTITION p20260614 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-15')),
PARTITION p20260615 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-16')),
PARTITION p20260616 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-17')),
PARTITION p20260617 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-18'))
);
-- ============================================
-- 改造 trends 为按月分区表
-- ============================================
ALTER TABLE trends PARTITION BY RANGE (clock) (
PARTITION p202606 VALUES LESS THAN (UNIX_TIMESTAMP('2026-07-01')),
PARTITION p202607 VALUES LESS THAN (UNIX_TIMESTAMP('2026-08-01'))
);
-- ============================================
-- 改造 trends_uint 为按月分区表
-- ============================================
ALTER TABLE trends_uint PARTITION BY RANGE (clock) (
PARTITION p202606 VALUES LESS THAN (UNIX_TIMESTAMP('2026-07-01')),
PARTITION p202607 VALUES LESS THAN (UNIX_TIMESTAMP('2026-08-01'))
);
第三步:创建自动分区存储过程
sql
DELIMITER $$
CREATE PROCEDURE zabbix.auto_add_daily_partitions()
BEGIN
DECLARE v_today DATE;
DECLARE v_partition_name VARCHAR(32);
DECLARE v_next_date DATE;
DECLARE v_drop_partition_name VARCHAR(32);
DECLARE v_drop_date DATE;
SET v_today = CURDATE();
-- ============================================
-- 一、清理过期分区
-- ============================================
-- 1.1 清理 history 系列(保留 30 天)
SET v_drop_date = DATE_SUB(v_today, INTERVAL 30 DAY);
SET v_drop_partition_name = CONCAT('p', DATE_FORMAT(v_drop_date, '%Y%m%d'));
-- history
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'history'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE history DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- history_bin
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'history_bin'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE history_bin DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- history_log
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'history_log'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE history_log DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- history_str
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'history_str'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE history_str DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- history_text
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'history_text'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE history_text DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- history_uint
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'history_uint'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE history_uint DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- 1.2 清理 trends 系列(保留 12 个月)
SET v_drop_date = DATE_SUB(v_today, INTERVAL 12 MONTH);
SET v_drop_partition_name = CONCAT('p', DATE_FORMAT(v_drop_date, '%Y%m'));
-- trends
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'trends'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE trends DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- trends_uint
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'trends_uint'
AND PARTITION_NAME = v_drop_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE trends_uint DROP PARTITION ', v_drop_partition_name);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- ============================================
-- 二、创建新分区
-- ============================================
-- 2.1 按日分区:history 系列 6 张表
SET v_partition_name = CONCAT('p', DATE_FORMAT(v_today, '%Y%m%d'));
SET v_next_date = DATE_ADD(v_today, INTERVAL 1 DAY);
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'history_uint'
AND PARTITION_NAME = v_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE history ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = CONCAT('ALTER TABLE history_bin ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = CONCAT('ALTER TABLE history_log ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = CONCAT('ALTER TABLE history_str ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = CONCAT('ALTER TABLE history_text ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = CONCAT('ALTER TABLE history_uint ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- 2.2 按月分区:trends / trends_uint(下个月)
SET v_partition_name = CONCAT('p', DATE_FORMAT(DATE_ADD(v_today, INTERVAL 1 MONTH), '%Y%m'));
SET v_next_date = DATE_ADD(DATE_ADD(v_today, INTERVAL 2 MONTH),
INTERVAL -DAY(DATE_ADD(v_today, INTERVAL 2 MONTH))+1 DAY);
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'trends'
AND PARTITION_NAME = v_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE trends ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = CONCAT('ALTER TABLE trends_uint ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
-- 2.3 按月分区:trends / trends_uint(当前月,防止新库没有)
SET v_partition_name = CONCAT('p', DATE_FORMAT(v_today, '%Y%m'));
SET v_next_date = DATE_ADD(DATE_ADD(v_today, INTERVAL 1 MONTH),
INTERVAL -DAY(DATE_ADD(v_today, INTERVAL 1 MONTH))+1 DAY);
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix' AND TABLE_NAME = 'trends'
AND PARTITION_NAME = v_partition_name) THEN
SET @sql = CONCAT('ALTER TABLE trends ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = CONCAT('ALTER TABLE trends_uint ADD PARTITION (PARTITION ', v_partition_name, ' VALUES LESS THAN (UNIX_TIMESTAMP(''', v_next_date, ''')))');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
END IF;
END$$
DELIMITER ;
第四步:创建定时事件
sql
-- 确保 Event Scheduler 已开启
SET GLOBAL event_scheduler = ON;
-- 创建每天凌晨 2:00 自动执行的事件
CREATE EVENT zabbix.daily_partition_event
ON SCHEDULE EVERY 1 DAY
STARTS CONCAT(CURDATE(), ' 02:00:00')
ON COMPLETION PRESERVE
ENABLE
COMMENT 'Zabbix 分区每日自动维护'
DO CALL auto_add_daily_partitions();
第五步:手动测试
sql
-- 手动执行一次存储过程
CALL zabbix.auto_add_daily_partitions();
-- 查看执行结果
SELECT '存储过程执行完成' AS status, NOW() AS exec_time;
验证测试
测试 1:检查分区结构
sql
SELECT
TABLE_NAME,
PARTITION_NAME,
TABLE_ROWS,
ROUND(DATA_LENGTH / 1024 / 1024, 2) AS size_mb
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix'
AND TABLE_NAME IN (
'history', 'history_bin', 'history_log', 'history_str',
'history_text', 'history_uint', 'trends', 'trends_uint'
)
ORDER BY TABLE_NAME, PARTITION_NAME;
预期结果:8 张表都有多个分区,今天日期的分区数据在增长。
测试 2:检查存储过程
sql
SHOW CREATE PROCEDURE zabbix.auto_add_daily_partitions;
预期结果:包含 INTERVAL 30 DAY 和 INTERVAL 12 MONTH。
测试 3:检查定时事件
sql
SELECT
EVENT_NAME,
STATUS,
INTERVAL_VALUE,
INTERVAL_FIELD,
LAST_EXECUTED
FROM INFORMATION_SCHEMA.EVENTS
WHERE EVENT_SCHEMA = 'zabbix';
预期结果:daily_partition_event 状态为 ENABLED。
测试 4:验证数据写入
sql
SELECT 'history_uint' AS tbl, COUNT(*) AS records,
MIN(FROM_UNIXTIME(clock)) AS earliest,
MAX(FROM_UNIXTIME(clock)) AS latest
FROM history_uint PARTITION (p20260611)
UNION ALL
SELECT 'history', COUNT(*), MIN(FROM_UNIXTIME(clock)), MAX(FROM_UNIXTIME(clock))
FROM history PARTITION (p20260611)
UNION ALL
SELECT 'trends_uint', COUNT(*), MIN(FROM_UNIXTIME(clock)), MAX(FROM_UNIXTIME(clock))
FROM trends_uint PARTITION (p202606)
UNION ALL
SELECT 'trends', COUNT(*), MIN(FROM_UNIXTIME(clock)), MAX(FROM_UNIXTIME(clock))
FROM trends PARTITION (p202606);
预期结果:各表 records > 0,时间范围正确。
测试 5:分区概况统计
sql
SELECT
TABLE_NAME,
COUNT(*) AS partition_count,
SUM(TABLE_ROWS) AS total_rows,
ROUND(SUM(DATA_LENGTH) / 1024 / 1024, 2) AS total_size_mb
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix'
AND TABLE_NAME IN (
'history', 'history_bin', 'history_log', 'history_str',
'history_text', 'history_uint', 'trends', 'trends_uint'
)
GROUP BY TABLE_NAME
ORDER BY TABLE_NAME;
日常维护
每日健康检查
sql
-- 快速查看主要表状态
SELECT
TABLE_NAME,
COUNT(*) AS partitions,
ROUND(SUM(DATA_LENGTH) / 1024 / 1024, 2) AS size_mb
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix'
AND TABLE_NAME IN ('history_uint', 'trends_uint')
GROUP BY TABLE_NAME;
修改保留时间
sql
-- 修改存储过程中的保留天数
-- 找到:SET v_drop_date = DATE_SUB(v_today, INTERVAL 30 DAY);
-- 改为需要的天数,例如 90 天:
-- SET v_drop_date = DATE_SUB(v_today, INTERVAL 90 DAY);
-- 然后 DROP + CREATE 重新创建存储过程
手动操作
sql
-- 手动添加分区
ALTER TABLE history_uint ADD PARTITION (
PARTITION p20260618 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-19'))
);
-- 手动删除分区(秒级完成)
ALTER TABLE history_uint DROP PARTITION p20260501;
故障处理
问题 1:定时事件未执行
sql
-- 检查并开启 Event Scheduler
SHOW VARIABLES LIKE 'event_scheduler';
SET GLOBAL event_scheduler = ON;
-- 在 /etc/my.cnf 中永久生效:
-- [mysqld]
-- event_scheduler=ON
-- 查看事件状态
SHOW EVENTS FROM zabbix;
问题 2:分区未自动创建
bash
# 查看错误日志
tail -50 /var/log/mariadb/mariadb.log
# 手动执行测试
mysql -uroot -p zabbix -e "CALL auto_add_daily_partitions();"
问题 3:磁盘空间不足
sql
-- 查看各分区大小
SELECT TABLE_NAME, PARTITION_NAME,
ROUND(DATA_LENGTH / 1024 / 1024, 2) AS size_mb
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'zabbix'
ORDER BY DATA_LENGTH DESC
LIMIT 10;
-- 紧急清理旧分区
ALTER TABLE history_uint DROP PARTITION p20260501;
问题 4:恢复误删分区
sql
-- 重新创建空分区(历史数据无法恢复)
ALTER TABLE history_uint ADD PARTITION (
PARTITION p20260501 VALUES LESS THAN (UNIX_TIMESTAMP('2026-05-02'))
);
附录
A. 监控脚本
bash
#!/bin/bash
# /usr/local/bin/zabbix_partition_check.sh
MYSQL_USER="root"
MYSQL_PASS="your_password"
# 检查分区数量
COUNT=$(mysql -u${MYSQL_USER} -p${MYSQL_PASS} -N -e "
SELECT COUNT(*) FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA='zabbix' AND TABLE_NAME='history_uint'
")
if [ "$COUNT" -lt 30 ]; then
echo "WARNING: Low partition count: $COUNT"
fi
# 检查事件状态
STATUS=$(mysql -u${MYSQL_USER} -p${MYSQL_PASS} -N -e "
SELECT STATUS FROM INFORMATION_SCHEMA.EVENTS
WHERE EVENT_SCHEMA='zabbix' AND EVENT_NAME='daily_partition_event'
")
if [ "$STATUS" != "ENABLED" ]; then
echo "WARNING: Event not enabled: $STATUS"
fi
B. 分区日期生成脚本
bash
#!/bin/bash
# 生成从今天起 N 天的分区 DDL
DAYS=7
for i in $(seq 0 $DAYS); do
PART_DATE=$(date -d "+$i days" +%Y%m%d)
NEXT_DATE=$(date -d "+$((i+1)) days" +%Y-%m-%d)
echo "PARTITION p${PART_DATE} VALUES LESS THAN (UNIX_TIMESTAMP('${NEXT_DATE}')),"
done
文档版本:v1.0
适用环境:Zabbix 6.x/7.x + MariaDB 10.x / MySQL 8.x