zabbix5.0 mysql表分区

zabbix mysql数据库表的分区步骤

zabbix经常出现Zabbix housekeeper processes more than 75% busy报警,报警时WEB访问就变得很慢,尤其是加载历史数据的图形。

使用网上的调优设置,修改过housekeeper的进程和间隔时间,效果都不太理想。wvbY1Vfe62d506e8a19c0.png

因此就按照网上的建议,做一下zabbix mysql的数据库表的分区吧。

使用mysql表分区来对history这种大表进行分区,但是一定要在数据量小的时候进行分区,当数据量达到好几十G设置几百G了还是采用第一种方法把数据清理了再作表分区。

我看了下我的数据,也是非常大。

[root@zabbix # find /netzbxdb/ -type f -print0 | xargs -0 du -h | sort -rh | head -n 1018G /netzbxdb/zabbix/history_uint.ibd5.1G /netzbxdb/zabbix/history.ibd2.1G /netzbxdb/zabbix/trends_uint.ibd1.1G /netzbxdb/binlog.0000511.1G /netzbxdb/binlog.0000501.1G /netzbxdb/binlog.000049

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

过程不写了,最后做法是清空zabbix历史数据,再进行分区。

步骤如下吧!

1,使用truncate命令清空zabbix 所有监控数据

-------------------------------------------------------truncate table history;optimize table history;------------------------------------------------------- truncate table history_str;optimize table history_str;-------------------------------------------------------truncate table history_uint;optimize table history_uint;-------------------------------------------------------truncate table trends;optimize table trends;-------------------------------------------------------truncate table trends_uint; optimize table trends_uint; -------------------------------------------------------truncate table events;optimize table events;-------------------------------------------------------

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

注意:这些命令会把zabbix所有的监控数据清空,只是清空监控数据,添加的主机,配置,拓扑图不会丢失。如果对监控数据比较看重的话注意备份数据库

truncate是删除了表,然后根据表结构重新建立。

2,创建sql文件

[root@zabbix ~]# vim partition.sql

DELIMITER $$CREATE PROCEDURE `partition_create`(SCHEMANAME varchar(64), TABLENAME varchar(64), PARTITIONNAME varchar(64), CLOCK int)BEGIN        /*           SCHEMANAME = The DB schema in which to make changes           TABLENAME = The table with partitions to potentially delete           PARTITIONNAME = The name of the partition to create        */        /*           Verify that the partition does not already exist        */        DECLARE RETROWS INT;        SELECT COUNT(1) INTO RETROWS        FROM information_schema.partitions        WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_description >= CLOCK;        IF RETROWS = 0 THEN        /*           1. Print a message indicating that a partition was created.           2. Create the SQL to create the partition.           3. Execute the SQL from #2.        */        SELECT CONCAT( "partition_create(", SCHEMANAME, ",", TABLENAME, ",", PARTITIONNAME, ",", CLOCK, ")" ) AS msg;        SET @sql = CONCAT( 'ALTER TABLE ', SCHEMANAME, '.', TABLENAME, ' ADD PARTITION (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', CLOCK, '));' );        PREPARE STMT FROM @sql;        EXECUTE STMT;        DEALLOCATE PREPARE STMT;        END IF;END$$DELIMITER ;DELIMITER $$CREATE PROCEDURE `partition_drop`(SCHEMANAME VARCHAR(64), TABLENAME VARCHAR(64), DELETE_BELOW_PARTITION_DATE BIGINT)BEGIN        /*           SCHEMANAME = The DB schema in which to make changes           TABLENAME = The table with partitions to potentially delete           DELETE_BELOW_PARTITION_DATE = Delete any partitions with names that are dates older than this one (yyyy-mm-dd)        */        DECLARE done INT DEFAULT FALSE;        DECLARE drop_part_name VARCHAR(16);        /*           Get a list of all the partitions that are older than the date           in DELETE_BELOW_PARTITION_DATE.  All partitions are prefixed with           a "p", so use SUBSTRING TO get rid of that character.        */        DECLARE myCursor CURSOR FOR        SELECT partition_name        FROM information_schema.partitions        WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND CAST(SUBSTRING(partition_name FROM 2) AS UNSIGNED) < DELETE_BELOW_PARTITION_DATE;        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;        /*           Create the basics for when we need to drop the partition.  Also, create           @drop_partitions to hold a comma-delimited list of all partitions that           should be deleted.        */        SET @alter_header = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " DROP PARTITION ");        SET @drop_partitions = "";        /*           Start looping through all the partitions that are too old.        */        OPEN myCursor;        read_loop: LOOP        FETCH myCursor INTO drop_part_name;        IF done THEN    LEAVE read_loop;        END IF;        SET @drop_partitions = IF(@drop_partitions = "", drop_part_name, CONCAT(@drop_partitions, ",", drop_part_name));        END LOOP;        IF @drop_partitions != "" THEN        /*           1. Build the SQL to drop all the necessary partitions.           2. Run the SQL to drop the partitions.           3. Print out the table partitions that were deleted.        */        SET @full_sql = CONCAT(@alter_header, @drop_partitions, ";");        PREPARE STMT FROM @full_sql;        EXECUTE STMT;        DEALLOCATE PREPARE STMT;        SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`, @drop_partitions AS `partitions_deleted`;        ELSE        /*           No partitions are being deleted, so print out "N/A" (Not applicable) to indicate           that no changes were made.        */        SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`, "N/A" AS `partitions_deleted`;        END IF;END$$DELIMITER ;DELIMITER $$CREATE PROCEDURE `partition_maintenance`(SCHEMA_NAME VARCHAR(32), TABLE_NAME VARCHAR(32), KEEP_DATA_DAYS INT, HOURLY_INTERVAL INT, CREATE_NEXT_INTERVALS INT)BEGIN        DECLARE OLDER_THAN_PARTITION_DATE VARCHAR(16);        DECLARE PARTITION_NAME VARCHAR(16);        DECLARE OLD_PARTITION_NAME VARCHAR(16);        DECLARE LESS_THAN_TIMESTAMP INT;        DECLARE CUR_TIME INT;        CALL partition_verify(SCHEMA_NAME, TABLE_NAME, HOURLY_INTERVAL);        SET CUR_TIME = UNIX_TIMESTAMP(DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00'));        SET @__interval = 1;        create_loop: LOOP        IF @__interval > CREATE_NEXT_INTERVALS THEN    LEAVE create_loop;        END IF;        SET LESS_THAN_TIMESTAMP = CUR_TIME + (HOURLY_INTERVAL * @__interval * 3600);        SET PARTITION_NAME = FROM_UNIXTIME(CUR_TIME + HOURLY_INTERVAL * (@__interval - 1) * 3600, 'p%Y%m%d%H00');        IF(PARTITION_NAME != OLD_PARTITION_NAME) THEN    CALL partition_create(SCHEMA_NAME, TABLE_NAME, PARTITION_NAME, LESS_THAN_TIMESTAMP);        END IF;        SET @__interval=@__interval+1;        SET OLD_PARTITION_NAME = PARTITION_NAME;        END LOOP;        SET OLDER_THAN_PARTITION_DATE=DATE_FORMAT(DATE_SUB(NOW(), INTERVAL KEEP_DATA_DAYS DAY), '%Y%m%d0000');        CALL partition_drop(SCHEMA_NAME, TABLE_NAME, OLDER_THAN_PARTITION_DATE);END$$DELIMITER ;DELIMITER $$CREATE PROCEDURE `partition_verify`(SCHEMANAME VARCHAR(64), TABLENAME VARCHAR(64), HOURLYINTERVAL INT(11))BEGIN        DECLARE PARTITION_NAME VARCHAR(16);        DECLARE RETROWS INT(11);        DECLARE FUTURE_TIMESTAMP TIMESTAMP;        /*         * Check if any partitions exist for the given SCHEMANAME.TABLENAME.         */        SELECT COUNT(1) INTO RETROWS        FROM information_schema.partitions        WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_name IS NULL;        /*         * If partitions do not exist, go ahead and partition the table         */        IF RETROWS = 1 THEN        /*         * Take the current date at 00:00:00 and add HOURLYINTERVAL to it.  This is the timestamp below which we will store values.         * We begin partitioning based on the beginning of a day.  This is because we don't want to generate a random partition         * that won't necessarily fall in line with the desired partition naming (ie: if the hour interval is 24 hours, we could         * end up creating a partition now named "p201403270600" when all other partitions will be like "p201403280000").         */        SET FUTURE_TIMESTAMP = TIMESTAMPADD(HOUR, HOURLYINTERVAL, CONCAT(CURDATE(), " ", '00:00:00'));        SET PARTITION_NAME = DATE_FORMAT(CURDATE(), 'p%Y%m%d%H00');        -- Create the partitioning query        SET @__PARTITION_SQL = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " PARTITION BY RANGE(`clock`)");        SET @__PARTITION_SQL = CONCAT(@__PARTITION_SQL, "(PARTITION ", PARTITION_NAME, " VALUES LESS THAN (", UNIX_TIMESTAMP(FUTURE_TIMESTAMP), "));");        -- Run the partitioning query        PREPARE STMT FROM @__PARTITION_SQL;        EXECUTE STMT;        DEALLOCATE PREPARE STMT;        END IF;END$$DELIMITER ;DELIMITER $$CREATE PROCEDURE`partition_maintenance_all`(SCHEMA_NAME VARCHAR(32))BEGIN               CALL partition_maintenance(SCHEMA_NAME, 'history', 90, 24, 14);

0 条评论

请先 登录 后评论
乐维君
乐维君

397 篇文章

作家榜 »

  1. 乐维君 397 文章
  2. YOHOHO 14 文章
  3. 机灵小和尚 13 文章
  4. 我是一只小菜鸡 12 文章
  5. 细雨闲花 11 文章
  6. 。。。 9 文章
  7. 御前侍卫张五哥 9 文章
  8. 小黄人 8 文章