Zabbix 数据清理的一系列操作
基本信息:
Zabbix 版本 4.0.9
MySQL 版本 5.5
一、问题
我们将 Zabbix
的数据存放在测试环境的 RDS (阿里云)上,但是这个 RDS 购买的时候就只有 10G 的存储,所以监控没有几个月,我们的数据库就报存储空间不足的预警了。
首先进行排查,是哪些表占用的存储空间比较多呢,我们发现主要是 history
和 history_uint
这两个表。占用空间最大的是 history_uint
表。
那么这两个表分别是存储什么内容呢?
history_uint
该表存储的是监控项的无符号整型的数据。
该数据的保存时长,取决于在监控项设置的 历史数据保留时长。
CREATE TABLE `history_uint` (
`itemid` bigint(20) unsigned NOT NULL,
`clock` int(11) NOT NULL DEFAULT '0',
`value` bigint(20) unsigned NOT NULL DEFAULT '0',
`ns` int(11) NOT NULL DEFAULT '0',
KEY `history_uint_1` (`itemid`,`clock`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
-
itemid 是 监控项 ID
-
clock 是数据的时间的时间戳(unix)
-
value 是监控项对应的数据值
-
ns 是 纳秒时间值(小于1s的值),
监控项的精确实际收集时间,是由 clock + ns 组成的。
history
这个表保存的是浮点型的。
像 history_str
等保存的是 字符型数据。这些都是我们在设置监控项的对应的信息类型决定的。
该数据的保存时长,取决于在监控项设置的 历史数据保留时长。
扩展
表 trends
是保存了趋势数据用的,和 history 不同的是,trends 表仅仅保存了
小时平均的值。所以 trends 表也有很多的类型,对应history。
二、解决办法
临时解决办法
针对这个问题,我们临时的解决办法就是,就删除 history_uint
和 history
的一些历史数据。
首先获取要删除时间的一个时间戳,比如我们要删除 2019年 9月10号 11点00之前的数据。那么这个时间对应的时间戳是 1568084400
.
我们进行删除 history_uint
里的数据,这里需要注意一个点,如果我们的数据量比较多的话,我们建议分多个时间段进行删除,比如我们数据库里面由 2018年 10月份到2019年10月份的数据 ,那么我们可以将里面的数据分成4个阶段进行删除,从 2018年10月份到 2019年1月份,从 2019年1月份到 2019年4月份,这样就可以避免一次性删除数据过多导致数据库的负载比较大。(或者也可以使用 limit 10000)
delete history_uint
delete from history_uint where clock < 1568084400 LIMIT 10000;
delete history
delete from history where clock < 1568084400 LIMIT 10000;
在执行完上面的删除操作之后,我们发现一个很异常的事情发生了。
就是我们删除了那么多的数据,但是数据的储存空间是没有减少的。反而增加了(这不是由于新增加的数据导致,后面觉得是阿里云的显示不准确).
原因是 :
对于delete from table_name where xxx带条件的删除, 不管是 innodb
还是 MyISAM
都不会释放磁盘空间.
为什么delete where 删除空间不会减少? 举个例子,一个公司有 100个工位,有100个人坐着,当有50个人离职了,但是他们的工位还是存在的,只有在把工位拆除了才会不存在, 它们的工位也是可以安装新入职的员工的.
所以我们需要进行 OPTIMIZE TABLE
操作,进行释放空间.
注意: 在optimize table '表名'
运行过程中,MySQL
会锁定表。
OPTIMIZE TABLE history_uint;
OPTIMIZE TABLE history;
在 RDS 操作完之后, 我们大概需要过几分钟才能在控制台看到我们的实际储存信息.
借鉴内容: https://blog.csdn.net/weixin_40596063/article/details/82978736
1、drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM ,不保留表结构,;
2、truncate table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM 。truncate table保留表结构,删除方式类似drop table;
3、delete from table_name删除表的全部数据,对于MyISAM 会立刻释放磁盘空间 ,InnoDB 不会释放磁盘空间;
4、对于delete from table_name where xxx带条件的删除, 不管是innodb还是MyISAM都不会释放磁盘空间;
5、对于delete操作(或带条件的delete)需要释放空间,在delete以后使用optimize table table_name 会立刻释放磁盘空间。不管是innodb还是myisam ;所以要想达到释放磁盘空间的目的,delete以后执行optimize table 操作。
对于delete之后未释放的空间。在insert时无需新开辟空间。会使用保留空间 。
永久解决办法
- 数据量过多是由于我们保存的历史数据的时间过长,我们可以设置 历史数据的保留时长,将该值设置的更短一些,这样数据量也就随着减少了。
- 扩大数据库的储存空间。