MySQL实现清空分区表单个分区数据

 更新时间:2023年03月13日 09:00:21   作者:Demonson  
这篇文章主要介绍了MySQL实现清空分区表单个分区数据方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

MySQL清空分区表单个分区数据

1.单个分区清空

ALTER TABLE xxx TRUNCATE PARTITION p20220104;

2.编辑存储过程

功能:指定清空之前某一天的数据,直接调用存储过程实现

DELIMITER $$
 
USE `managerdb`$$
 
DROP PROCEDURE IF EXISTS `partition_trunc`$$
 
CREATE DEFINER=`root`@`localhost` PROCEDURE `partition_trunc`(p_schema_name VARCHAR(64), p_table_name VARCHAR(64), p_trunc_before_date INT)
BEGIN
/*
p_trunc_before_date 清空分区表第N天的数据
*/      
        DECLARE trunc_part_name VARCHAR(16);
		
        SET trunc_part_name = CONCAT('p',DATE_FORMAT(DATE_SUB(CURDATE(),INTERVAL p_trunc_before_date DAY),'%Y%m%d'));
        SET @trunc_partitions = CONCAT("ALTER TABLE ", p_schema_name, ".", p_table_name, " TRUNCATE PARTITION ",trunc_part_name); -- 拼执行语句
		
	SELECT @trunc_partitions; -- 打印删除详情
        
         PREPARE STMT FROM @trunc_partitions;
                
         EXECUTE STMT;
                
         DEALLOCATE PREPARE STMT;
        
END$$
 
DELIMITER ;

实例:

call managerdb.partition_trunc('test','t_001',1);

清空test.t_001一天前的单个分区数据

MySQL自动分区自动清理

mysql分区表功能特别有用,其中一个应用就是保存固定时间的数据信息,自动分区自动purge,不用担心数据量越积累越多。

比较实用的一个实现方式是表一天一个分区,保持固定天数的数据。

完整的SQL

以数据库log为例,里面有一个表tb_log, 按天分区,始终保存最新的30天的数据。

存储过程sp_create_log_partition和sp_drop_log_partition用于创建和删除分区。

事件event_log_auto_partition每天执行一次,用于向前创建新的分区和删除过期的分区。

存储过程和事件结合使用就实现了tb_log数据的自动分区自动删除。

--
-- Definition for database log
--
DROP DATABASE IF EXISTS log;
CREATE DATABASE IF NOT EXISTS log
CHARACTER SET utf8
COLLATE utf8_general_ci;
 
-- 
-- Set default database
--
USE log;
 
--
-- Definition for table tb_log
--
CREATE TABLE IF NOT EXISTS tb_log (
  id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  log varchar(512) NOT NULL DEFAULT '',
  PRIMARY KEY (id, created_at)
)
ENGINE = INNODB
AUTO_INCREMENT = 1
AVG_ROW_LENGTH = 16384
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci
PARTITION BY RANGE(TO_DAYS(created_at))
(
PARTITION pbasic VALUES LESS THAN (0)
);
 
DELIMITER $$
 
--
-- Definition for procedure sp_create_log_partition
--
CREATE DEFINER = 'uiadmin'@'%'
PROCEDURE sp_create_log_partition (day_value datetime, tb_name varchar(128))
BEGIN
  DECLARE par_name varchar(32);
  DECLARE par_value varchar(32);
  DECLARE _err int(1);
  DECLARE par_exist int(1);
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND SET _err = 1;
  START TRANSACTION;
    SET par_name = CONCAT('p', DATE_FORMAT(day_value, '%Y%m%d'));
    SELECT
      COUNT(1) INTO par_exist
    FROM information_schema.PARTITIONS
    WHERE TABLE_SCHEMA = 'log' AND TABLE_NAME = tb_name AND PARTITION_NAME = par_name;
    IF (par_exist = 0) THEN
      SET par_value = DATE_FORMAT(day_value, '%Y-%m-%d');
      SET @alter_sql = CONCAT('alter table ', tb_name, ' add PARTITION (PARTITION ', par_name, ' VALUES LESS THAN (TO_DAYS("', par_value, '")+1))');
      PREPARE stmt1 FROM @alter_sql;
      EXECUTE stmt1;
    END IF;
  END
  $$
 
--
-- Definition for procedure sp_drop_log_partition
--
CREATE DEFINER = 'uiadmin'@'%'
PROCEDURE sp_drop_log_partition (day_value datetime, tb_name varchar(128))
BEGIN
  DECLARE str_day varchar(64);
  DECLARE _err int(1);
  DECLARE done int DEFAULT 0;
  DECLARE par_name varchar(64);
  DECLARE cur_partition_name CURSOR FOR
  SELECT
    partition_name
  FROM INFORMATION_SCHEMA.PARTITIONS
  WHERE TABLE_SCHEMA = 'log' AND table_name = tb_name
  ORDER BY partition_ordinal_position;
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND SET _err = 1;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
  SET str_day = DATE_FORMAT(day_value, '%Y%m%d');
  OPEN cur_partition_name;
  REPEAT
    FETCH cur_partition_name INTO par_name;
    IF (str_day > SUBSTRING(par_name, 2)) THEN
      SET @alter_sql = CONCAT('alter table ', tb_name, ' drop PARTITION ', par_name);
      PREPARE stmt1 FROM @alter_sql;
      EXECUTE stmt1;
    END IF;
  UNTIL done END REPEAT;
  CLOSE cur_partition_name;
END
$$
 
--
-- Definition for event event_log_auto_partition
--
CREATE
DEFINER = 'uiadmin'@'%'
EVENT event_log_auto_partition
ON SCHEDULE EVERY '1' DAY
STARTS '1972-01-01 00:00:00'
ON COMPLETION PRESERVE
DO
BEGIN
  CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL - 3 DAY), 'tb_log');
  CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL - 2 DAY), 'tb_log');
  CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL - 1 DAY), 'tb_log');
  CALL sp_create_log_partition(NOW(), 'tb_log');
  CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL 1 DAY), 'tb_log');
  CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL 2 DAY), 'tb_log');
  CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL 3 DAY), 'tb_log');
  CALL sp_drop_log_partition(DATE_ADD(NOW(), INTERVAL - 30 DAY), 'tb_log');
 
END
$$
 
--
-- Create partitions based on current time
--
CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL - 3 DAY), 'tb_log')$$
CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL - 2 DAY), 'tb_log')$$
CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL - 1 DAY), 'tb_log')$$
CALL sp_create_log_partition(NOW(), 'tb_log')$$
CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL 1 DAY), 'tb_log')$$
CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL 2 DAY), 'tb_log')$$
CALL sp_create_log_partition(DATE_ADD(NOW(), INTERVAL 3 DAY), 'tb_log')$$
 
DELIMITER ;

查看分区

select TABLE_SCHEMA, TABLE_NAME,PARTITION_NAME from INFORMATION_SCHEMA.PARTITIONS where TABLE_SCHEMA='log' and table_name='tb_log';

在磁盘上一个分区表现为一个文件,所以删除操作会很快完成的。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • ubuntu20.04 安装 MySQL5.7过程记录

    ubuntu20.04 安装 MySQL5.7过程记录

    这篇文章主要介绍了ubuntu20.04 安装 MySQL5.7过程记录的相关资料,需要的朋友可以参考下
    2022-10-10
  • mysql 8.0.24 安装配置方法图文教程

    mysql 8.0.24 安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 8.0.24 安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • MySql 字符串中提取数字的实现示例

    MySql 字符串中提取数字的实现示例

    在MySQL中,有时需要从字符串中提取数字,本文就来介绍一下MySql 字符串中提取数字的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • MySQL运算符!=和<>及=和<=>的使用区别

    MySQL运算符!=和<>及=和<=>的使用区别

    本文主要介绍了MySQL运算符!=和<>及=和<=>的使用区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • mysql 5.7.16 安装配置方法图文教程

    mysql 5.7.16 安装配置方法图文教程

    这篇文章主要为大家分享了mysql 5.7.16winx64安装配置方法图文教程,感兴趣的朋友可以参考一下
    2016-10-10
  • MySQL之存储过程按月创建表的方法步骤

    MySQL之存储过程按月创建表的方法步骤

    这篇文章主要介绍了MySQL之存储过程按月创建表的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • MySQL各个特殊时间段的查询方法

    MySQL各个特殊时间段的查询方法

    在MySQL数据库中,经常需要查询某个时间段内的数据,所以本文给大家介绍了MySQL各个特殊时间段的查询方法,并提供相应的源代码示例,具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • mysql show操作简单示例

    mysql show操作简单示例

    这篇文章主要介绍了mysql show操作,结合简单实例形式总结分析了mysql使用show语句显示各种常见信息相关操作技巧,需要的朋友可以参考下
    2019-04-04
  • MySQL索引长度限制原理解析

    MySQL索引长度限制原理解析

    这篇文章主要介绍了MySQL索引长度限制原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 对MySQL子查询的简单改写优化

    对MySQL子查询的简单改写优化

    这篇文章主要介绍了对MySQL子查询的简单改写优化,文中的小修改主要将子查询改为关联从而降低查询时关联的次数,需要的朋友可以参考下
    2015-05-05

最新评论