zabbix数据太多,卡顿,分表,存储过程

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
相关推荐
风曦Kisaki8 小时前
#Linux监控与安全Day02:Zabbix 自动发现,Zabbix 报警机制,Zabbix 主动监控,监控 Nginx 服务
linux·运维·nginx·安全·自动化·云计算·zabbix
梁正雄16 小时前
zabbix监控-主机-1
zabbix·监控·zabbix主机指标
风曦Kisaki1 天前
#Linux监控与安全Day01:Zabbix部署全流程,基础监控配置与自定义监控项
linux·运维·安全·云计算·zabbix
lvbinemail2 天前
【无标题】
数据库·postgresql·zabbix·监控
蜀道山老天师6 天前
Docker 实战教程:从基础流程到云桌面、Zabbix 监控、Portainer 可视化部署
运维·docker·云原生·容器·zabbix
万山寒6 天前
zabbix设置中文
zabbix
securitor7 天前
zabbix-agent 安装
zabbix
梁正雄8 天前
zabbix安装-7.4
zabbix·监控·zabbix安装·zabbix7.4·zabbix7.4最新安装包
m0_736034859 天前
zabbix
zabbix