我的编程空间,编程开发者的网络收藏夹
学习永远不晚

zabbix上怎么对mysql数据库做分区表

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

zabbix上怎么对mysql数据库做分区表

本篇内容介绍了“zabbix上怎么对mysql数据库做分区表”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

独立表空间设置:

innodb_file_per_table=1

修改表索引:

zabbix3.2以上版本跳过此步骤

mysql> Alter table history_text drop primary key, add index (id), drop index history_text_2, add index history_text_2 (itemid, id);

Query OK, 0 rows affected (0.49 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> Alter table history_log drop primary key, add index (id), drop index history_log_2, add index history_log_2 (itemid, id);

Query OK, 0 rows affected (2.71 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql>

创建存储过程:

增加分区存储过程:

DELIMITER $$CREATE PROCEDURE `partition_create`(SCHEMANAME varchar(64), TABLENAME varchar(64), PARTITIONNAME varchar(64), CLOCK int)BEGIN
        
        
        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
                
                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
        
        DECLARE done INT DEFAULT FALSE;
        DECLARE drop_part_name VARCHAR(16);
        
        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;
        
        SET @alter_header = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " DROP PARTITION ");
        SET @drop_partitions = "";
        
        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
                
                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
                
                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;
        
        SELECT COUNT(1) INTO RETROWS
        FROM information_schema.partitions
        WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_name IS NULL;
        
        IF RETROWS = 1 THEN
                
                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 ;

将上面4个存储过程语句写到一个sql文件里,partition_call.sql

执行:mysql  -uzabbix -p'zabbixzabbix < partition_call.sql

使用存储过程:

mysql>  CALL partition_maintenance('<zabbix_db_name>', '<table_name>', <days_to_keep_data>, <hourly_interval>, <num_future_intervals_to_create>)

zabbix_db_name:库名

table_name:表名

days_to_keep_data:保存多少天数据

hourly_interval:每隔多久生成一个分区

num_future_intervals_to_create:本次一共生成多少个分区

例如:

mysql> CALL partition_maintenance('zabbix', 'history', 7, 24, 7);

这个例子就是history表最多保存7天数据,每隔24小时生成一个分区,这次一共生成7个分区

统一调用存储过程:

DELIMITER $$
CREATE PROCEDURE `partition_maintenance_all`(SCHEMA_NAME VARCHAR(32))BEGIN
                CALL partition_maintenance(SCHEMA_NAME, 'history', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_log', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_str', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_text', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_uint', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'trends', 730, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'trends_uint', 730, 24, 14);END$$
DELIMITER ;

将这条语句保存成sql文件 partition_all.sql,再次导入存储过程

mysql  -uzabbix -p'zabbixzabbix < partition_all.sql

计划任务每天调用一次:

注意:

若数据量比较大,首次执行时间较长,请使用nohup执行(我当时执行了15个小时左右,这期间zabbix是无法正常工作,获取agent数据不展示,但数据不会丢失)

nohup time mysql -uzabbix -pzabbix zabbix -e "CALL partition_maintenance_all('zabbix');" &> /tmp/file.txt &

后面只需要调用这个存储过程就可以了,每天执行一次:

mysql -uzabbix -pzabbix zabbix -e "CALL partition_maintenance_all('zabbix');"

写成crontab:

# crontab -e

0 1 * * * /data/tools/mysql/bin/mysql -uzabbix -pzabbix zabbix -e "CALL partition_maintenance_all('zabbix');"

执行脚本:

mysql> CALL partition_maintenance('zabbix', 'history', 28, 24, 14);
+-----------------------------------------------------------+
| msg                                                       |
+-----------------------------------------------------------+
| partition_create(zabbix,history,p201404160000,1397718000) |
+-----------------------------------------------------------+
1 row in set (0.39 sec)
+-----------------------------------------------------------+
| msg                                                       |
+-----------------------------------------------------------+
| partition_create(zabbix,history,p201404170000,1397804400) |
+-----------------------------------------------------------+
1 row in set (0.51 sec)
mysql> CALL partition_maintenance_all('zabbix');
+----------------+--------------------+
| table          | partitions_deleted |
+----------------+--------------------+
| zabbix.history | N/A                |
+----------------+--------------------+
1 row in set (0.01 sec)
....
....
....
+--------------------+--------------------+
| table              | partitions_deleted |
+--------------------+--------------------+
| zabbix.trends_uint | N/A                |
+--------------------+--------------------+
1 row in set (22.85 sec)
Query OK, 0 rows affected, 1 warning (22.85 sec)

[root@hk-zabbix ~]# mysql -uzabbix -p'zabbix' zabbix -e "CALL partition_maintenance_all('zabbix');"

mysql: [Warning] Using a password on the command line interface can be insecure.

+-----------------------------------------------------------+

| msg                                                       |

+-----------------------------------------------------------+

| partition_create(zabbix,history,p201811080000,1541692800) |

+-----------------------------------------------------------+

+-----------------------------------------------------------+

| msg                                                       |

+-----------------------------------------------------------+

| partition_create(zabbix,history,p201811090000,1541779200) |

关闭housekeeping:

zabbix上怎么对mysql数据库做分区表

完成。

“zabbix上怎么对mysql数据库做分区表”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

zabbix上怎么对mysql数据库做分区表

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Zabbix系统MySQL数据库分区表的设定--精简说明

Zabbix监控中对后台MySQL DB几张历史大表依照时间进行分区无疑可以提高zabbix by时间查询时的性能,可以在zabbix后台DB在安装之初就将table设定为分区表,也可以在使用一段时间后已经有时间的情况下设定table为分区
2023-06-04

怎么在MySQL中分表分库时对数据进行切分

今天就跟大家聊聊有关怎么在MySQL中分表分库时对数据进行切分,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。数据库分布式核心内容无非就是数据切分(Sharding)以及切分后对数据的
2023-06-14

MySQL插入锁与数据库分区分表

MySQL的插入锁是指在对表进行插入操作时,MySQL会对整个表进行加锁,这样其他对该表的操作会被阻塞,直到插入操作完成。这种锁的存在可以保证插入操作的原子性,但也可能导致其他操作的阻塞。数据库分区分表是指将一个表按照一定的规则分成多个分
MySQL插入锁与数据库分区分表
2024-08-19

MySQL数据库分区表设计原则

MySQL数据库分区表设计原则涉及多个方面,以下是一些关键原则:选择合适的分区键:分区键应该是经常用于查询和筛选的字段,同时要确保分区键的数据分布均匀,避免数据倾斜。根据查询频率进行分区:将经常查询的数据放在较小的分区中,减少查询范围,加
MySQL数据库分区表设计原则
2024-10-21

MySQL 分表分库怎么进行数据切分

关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数
2022-05-23

MySQL对数据表已有表进行分区表的实现方法是什么

本篇内容介绍了“MySQL对数据表已有表进行分区表的实现方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!操作方式@1 可以使用ALT
2023-06-25

编程热搜

目录