本文使用分区脚本在 MySQL 或 MariaDB 上对 Zabbix 数据库(历史和趋势表)进行分区。Zabbix 从主机收集数据并使用历史和趋势表将它们存储在数据库中。Zabbix 历史记录保留原始数据(Zabbix 收集的每个值),趋势存储合并的每小时数据,平均为 min、avg 和 max。Zabbix 的管家进程负责删除旧的趋势和历史数据。使用 SQL 删除查询从数据库中删除旧数据会对数据库性能产生负面影响。因此,我们中的许多人都收到了那个烦人的警报“ Zabbix housekeeper processes more than 75% busy”。
使用数据库分区可以轻松解决该问题。分区每小时或每天创建表,并在不再需要时删除它们。SQL DROP 比 DELETE 语句更有效。适用于 3.0 之后的任何 Zabbix 版本(3.2、3.4、4.0、4.2、4.4、5.0、5.2 等)。请备份 Zabbix 数据库,但如果是新安装,则无需备份。
wget http://bestmonitoringtools.com/dl/zbx_db_partitiong.tar.gz
tar -zxvf zbx_db_partitiong.tar.gz
脚本“ zbx_db_partitiong.sql”被配置为保留 7 天的历史数据和 365 天的趋势数据;但是,如果要更改趋势或历史的天数,请打开文件“ zbx_db_partitiong.sql ”,如下图所示更改设置,然后保存文件。
运行脚本的语法是 mysql -u '
脚本将在新的 Zabbix 安装上非常快速地创建 MySQL 分区程序,但在已存在的库上,这可能会持续数小时。
[root@localhost zabbix]# mysql -uroot -ppwd zabbix < /root/zbx_db_partitiong.sql
##查看分区过程
MariaDB [(none)]> show procedure status ;
+--------+---------------------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+--------+---------------------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| zabbix | partition_create | PROCEDURE | root@localhost | 2021-09-22 10:00:20 | 2021-09-22 10:00:20 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
| zabbix | partition_drop | PROCEDURE | root@localhost | 2021-09-22 10:00:21 | 2021-09-22 10:00:21 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
| zabbix | partition_maintenance | PROCEDURE | root@localhost | 2021-09-22 10:00:21 | 2021-09-22 10:00:21 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
| zabbix | partition_maintenance_all | PROCEDURE | root@localhost | 2021-09-22 10:00:21 | 2021-09-22 10:00:21 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
| zabbix | partition_verify | PROCEDURE | root@localhost | 2021-09-22 10:00:21 | 2021-09-22 10:00:21 | DEFINER | | utf8 | utf8_general_ci | utf8_general_ci |
+--------+---------------------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
5 rows in set (0.00 sec)
已经创建了分区过程,但是在我们运行它们之前它们什么都不做!这步是最重要的,因为必须使用分区程序定期(每天)删除和创建分区!对于此类任务,我们可以使用两种工具:MySQL 事件调度程序或Crontab – 选择您喜欢的任何工具。
默认情况下,禁用 MySQL 事件调度程序。您需要通过在 MySQL 配置文件中的“[mysqld]”行之后设置“ event_scheduler=ON ”来启用它。
###完成更改后,请重新启动 MySQL 服务器以使设置生效!
[mysqld]
event_scheduler = ON
可以创建一个事件,它将每 12 小时运行一次程序“ partition_maintenance_all ”。
MySQL -u 'ZABBIX' -p 'zabbixDBpass' ZABBIX -e "CREATE EVENT zbx_partitioning ON SCHEDULE EVERY 12 HOUR DO CALL partition_maintenance_all('ZABBIX');"
###12 小时后,使用以下命令检查事件是否已成功执行
mysql -u 'zabbix' -p'zabbixDBpass' zabbix -e "SELECT * FROM INFORMATION_SCHEMA.events\G"
如果您无法使用 MySQL 事件调度程序,Crontab 是一个不错的选择。使用命令“ sudo crontab -e ”打开 crontab 文件,并通过在文件中的任何位置添加以下行来添加用于分区 Zabbix MySQL 数据库的作业(每天上午 03:30):
30 03 * * * /usr/bin/mysql -u 'zabbix' -p'zabbixDBpass' zabbix -e "CALL partition_maintenance_all('zabbix');" > /tmp/CronDBpartitiong.log 2>&1
Cron 将每天执行分区(删除旧表并创建新表)并将所有内容记录在文件“ /tmp/CronDBpartitiong.log”中
你也可以直接在终端运行此命令
[root@localhost zabbix]# mysql -u 'zabbix' -p'zabbixDBpass' zabbix -e "CALL partition_maintenance_all('zabbix');"
然后检查分区状态:
mysql -u 'zabbix' -p'zabbixDBpass' zabbix -e "show create table history\G"
section: “Administration” → “General” → “Housekeeping“;
如上图:取消历史记录与趋势的勾选,然后更新。
至此已成功在 Zabbix 数据库上对 MySQL 表进行了分区!
有时可能会发生,您最初为 Zabbix 数据库的历史和趋势设置了太多天数,因此磁盘空间太快填满。或者相反的情况,您没有为历史或趋势配置足够的天数。那该怎么办呢?
您不需要再次运行该脚本,只需创建一个您将运行的新程序而不是旧程序。
###将设置为历史30天和400天的趋势,根据你的配置设置下面的数字
[root@localhost zabbix]# mysql -uroot -p
DELIMITER $$
CREATE PROCEDURE partition_maintenance_all_30and400(SCHEMA_NAME VARCHAR(32))
BEGIN
CALL partition_maintenance(SCHEMA_NAME, 'history', 30, 24, 3);
CALL partition_maintenance(SCHEMA_NAME, 'history_log', 30, 24, 3);
CALL partition_maintenance(SCHEMA_NAME, 'history_str', 30, 24, 3);
CALL partition_maintenance(SCHEMA_NAME, 'history_text', 30, 24, 3);
CALL partition_maintenance(SCHEMA_NAME, 'history_uint', 30, 24, 3);
CALL partition_maintenance(SCHEMA_NAME, 'trends', 400, 24, 3);
CALL partition_maintenance(SCHEMA_NAME, 'trends_uint', 400, 24, 3);
END$$
DELIMITER ;
更新 MySQL 事件调度程序,如果你用的不是crontab,使用此命令将旧程序替换为新程序。
mysql -u 'zabbix' -p'zabbixDBpass' zabbix -e "ALTER EVENT zbx_partitioning ON SCHEDULE EVERY 12 HOUR DO CALL partition_maintenance_all_30and400('zabbix');"
更新crontab
30 03 * * * /usr/bin/mysql -u 'zabbix' -p'zabbixDBpass' zabbix -e "CALL partition_maintenance_all_30and400('zabbix');" > /tmp/CronDBpartitiong.log 2>&1
经测试30-40G的zabbix数据库分区时间很长,可以先做一个从库, 然后切换zabbix数据库,然后做分区,再切换回去。中间通过主从来减少差异。