已索引
参考:https://zabbix.org/wiki/Docs/howto/MySQL_Table_Partitioning_(variant)
需要分区的表
下面这些表会越来越大,需要做成分区表,以优化查询并方便后期我们删除旧分区。
历史表:history、history_log、history_str、history_text、history_uint
趋势表:trends、trends_uint
将表修改为分区表
查看最小值:
SELECT FROM_UNIXTIME(MIN(clock)) FROM zabbix.history_uint;
select count(1) from zabbix.history_uint;
目前我们已经对上面的表都采用了“按月分区”,语句如下:
for tabname in history history_log history_str history_text history_uint trends trends_uint; do
mysql -uroot -p'xxxxx' <<EOF
use zabbix;
ALTER TABLE $tabname PARTITION BY RANGE (clock)
(PARTITION p2020_08 VALUES LESS THAN (UNIX_TIMESTAMP("2020-09-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2020_09 VALUES LESS THAN (UNIX_TIMESTAMP("2020-10-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2020_10 VALUES LESS THAN (UNIX_TIMESTAMP("2020-11-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2020_11 VALUES LESS THAN (UNIX_TIMESTAMP("2020-12-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2020_12 VALUES LESS THAN (UNIX_TIMESTAMP("2021-01-01 00:00:00")) ENGINE = InnoDB);
EOF
done
如果想做成"按日分区",参考语法如下:
ALTER TABLE $tabname PARTITION BY RANGE (clock)
(PARTITION p2020_08_15 VALUES LESS THAN (UNIX_TIMESTAMP("2020-08-16 00:00:00")) ENGINE = InnoDB,
PARTITION p2020_08_16 VALUES LESS THAN (UNIX_TIMESTAMP("2020-08-17 00:00:00")) ENGINE = InnoDB);
查看分区
查询当前数据库分区情况:
mysql> select TABLE_SCHEMA,TABLE_NAME,PARTITION_NAME from information_schema.partitions where PARTITION_NAME is not NULL;
增加分区
先查询一下当前的分区情况,然后对上面所有的表增加以后需要使用的分区。
注意:如果没有提前创建好分区,zabbix 仍然能告警,但是在 Operational data 那儿就不能查看详情历史数据了。
语句如下:(只需要修改年份即可)
for tabname in history history_log history_str history_text history_uint trends trends_uint; do
mysql -uroot -p'xxxxx' <<EOF
use zabbix;
ALTER TABLE history_uint ADD PARTITION
(PARTITION p2024_01 VALUES LESS THAN (UNIX_TIMESTAMP("2024-02-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_02 VALUES LESS THAN (UNIX_TIMESTAMP("2024-03-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_03 VALUES LESS THAN (UNIX_TIMESTAMP("2024-04-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_04 VALUES LESS THAN (UNIX_TIMESTAMP("2024-05-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_05 VALUES LESS THAN (UNIX_TIMESTAMP("2024-06-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_06 VALUES LESS THAN (UNIX_TIMESTAMP("2024-07-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_07 VALUES LESS THAN (UNIX_TIMESTAMP("2024-08-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_08 VALUES LESS THAN (UNIX_TIMESTAMP("2024-09-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_09 VALUES LESS THAN (UNIX_TIMESTAMP("2024-10-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_10 VALUES LESS THAN (UNIX_TIMESTAMP("2024-11-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_11 VALUES LESS THAN (UNIX_TIMESTAMP("2024-12-01 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_12 VALUES LESS THAN (UNIX_TIMESTAMP("2025-01-01 00:00:00")) ENGINE = InnoDB);
EOF
done
删除数据库分区
先查询一下当前的分区情况,然后删除过早的分区。
历史数据较大,可以根据实际情况设置保留时间,比如3个月。
趋势数据因为是计算后保留的数据,并不大,可以保留长一些,比如1年。
但是,如果我们采用了分区表,可以通过删除分区的方式来清理数据,上面的历史数据和趋势数据设置就不是很重要。
趋势的分区可以半年或者1年清理一次,历史的分区建议3个月清理一次。
我们这儿历史数据和趋势数据都只保留3个月。
语句如下:(只需要修改月份变量值和年份即可)
for monthnum in 10 11 12; do
mysql -uroot -p'xxxxx' <<EOF
use zabbix;
alter table history drop partition p2023_$monthnum;
alter table history_log drop partition p2023_$monthnum;
alter table history_str drop partition p2023_$monthnum;
alter table history_text drop partition p2023_$monthnum;
alter table history_uint drop partition p2023_$monthnum;
alter table trends drop partition p2023_$monthnum;
alter table trends_uint drop partition p2023_$monthnum;
EOF
done