【mysql表分区系】mysql表分区谨慎使用DROP PARTITION语法以及TRUNCATE PARTITION

首先声明下我这边使用的mysql版本是5.7.29版本,当然下面的问题我这边也是基于这个版本。这里因为没有考证其他版本是否也会有这些问题,可自行官方文档来查阅资料

为什么说要谨慎使用DROP PARTITION 语法呢?

请看官网的解释

It is very important to remember that, when you drop a partition, you also delete all the data that was stored in that partition

翻译过来就是说请务必记住,当您删除分区时,您还会删除该分区中存储的所有数据

那这里有人就问了,如果我只是想删除分区,我不想删除数据怎么办呢?不急,官网给了我们答案

If you intend to change the partitioning of a table without losing data, use ALTER TABLE ... REORGANIZE PARTITION instead.

对就是使用ALTER TABLE ... REORGANIZE PARTITION 语法

示例DROP PARTITION 来演示

初始化表数据

CREATE TABLE test_order (
    id INT NOT NULL ,
    order_no varchar(20) not null ,
    create_time DATE NOT NULL,
    PRIMARY KEY(id,create_time),
    UNIQUE KEY(order_no,create_time)
)ENGINE=InnoDB  DEFAULT CHARSET=utf8;
 
insert into  test_order  VALUES(1,'001','2023-01-01');
insert into  test_order  VALUES(2,'002','2023-02-01');
insert into  test_order  VALUES(3,'003','2023-03-01');

根据创建时间字段来使用range做表分区

alter table test_order  partition by range (TO_DAYS(CREATE_TIME)) (
 
	partition p_202301 values less than (TO_DAYS('2023-02-01')),
	partition p_202302 values less than (TO_DAYS('2023-03-01')),
	partition p_202303 values less than (TO_DAYS('2023-04-01'))
);

查询当前分区下的数据

select *  from test_order  PARTITION (p_202302 ); 

 执行DROP PARTITION

ALTER TABLE test_order DROP PARTITION p_202302;

 看到执行DROP PARTITION的 后果没,数据丢了,这个在生产上面的话,那就GG了。

示例REORGANIZE  PARTITION 来演示

一般REORGANIZE PARTITION 如下所示

ALTER TABLE tbl_name REORGANIZE PARTITION partition_list INTO (partition_definitions);

这里,tbl_name是分区表的名称,partition_list 是要更改的一个或多个现有分区的名称的逗号分隔列表。 partition_definitions是新分区定义的逗号分隔列表

使用或ALTER TABLE ... REORGANIZE PARTITION(重组分区)重新分区表 时要记住以下一些要点

用于确定新分区方案的选项PARTITION与语句中使用的选项遵循相同的规则CREATE TABLE

  • 新的RANGE分区方案不能有任何重叠范围
  • 对于按 分区的表RANGE,只能重组相邻分区;您不能跳过范围分区
  • 不能用于REORGANIZE PARTITION更改表使用的分区类型

回归之前我们的需求问题,我们指向删除分区而不是删除数据,换种思路想,是不是因为之前创建分区不合理,现在想重新换种方式来创建分区呢,怎么来做?

比如之前我们这里设置分区 partition p_202302 values less than (TO_DAYS('2023-03-01')) 但是这句写成了 partition p_202302 values less than (TO_DAYS('2023-04-01'))

我们先清除下上面例子的分区,使然后使用错误的分区语句创建下

alter table  test_order remove partitioning;

REMOVE PARTITIONING使您能够删除表的分区,而不会影响表或其数据

模拟制造错误的分区创建语句

alter table test_order  partition by range (TO_DAYS(CREATE_TIME)) (
 
	partition p_202301 values less than (TO_DAYS('2023-02-01')),
	partition p_202302 values less than (TO_DAYS('2023-04-01')),
	partition p_202303 values less than (TO_DAYS('2023-05-01'))
);

查看我们的表分区信息

SELECT
    PARTITION_NAME,
    PARTITION_METHOD,
    PARTITION_EXPRESSION,
    PARTITION_DESCRIPTION,
    FROM_DAYS(PARTITION_DESCRIPTION),
    TABLE_ROWS,
    SUBPARTITION_NAME,
    SUBPARTITION_METHOD,
    SUBPARTITION_EXPRESSION 
FROM
    information_schema.PARTITIONS 
WHERE
    TABLE_SCHEMA = SCHEMA () 
    AND TABLE_NAME = 'test_order';

思路创建一个分区p_202302来筛分为两个新的子分区p_202302_1 ,p_202303_1 

ALTER TABLE test_order REORGANIZE PARTITION p_202302 INTO (
    PARTITION p_202302_1 VALUES LESS THAN (TO_DAYS('2023-03-01')),
    PARTITION p_202303_1 VALUES LESS THAN (TO_DAYS('2023-04-01'))
);

查询分区信息 我们已经将  (TO_DAYS('2023-03-01')) 拆分到单独的一个分区了

当然我们也可以将 p_202302_1 ,p_202303_1  分区合并为新的分区p_202302  

ALTER TABLE test_order REORGANIZE PARTITION p_202302_1, p_202303_1 INTO (
    PARTITION p_202302  VALUES LESS THAN (TO_DAYS('2023-04-01'))
);

查看分区信息

演示TRUNCATE PARTITION

直接上sql运行看效果

ALTER TABLE test_order TRUNCATE PARTITION p_202301, p_202302;

 发现TRUNCATE PARTITION 也是会删除表数据,谨慎操作啊。

有一点和DROP PARTITION 执行不同的结果是

 我们看到分区定义还是没有变化,但是DROP PARTITION 执行,分区的定义也是对应会删除

关于分区的具体操作可以查阅文档

关于重建分区

如果你之前表分区的创建不合理,想重新规划,这里我提供两个思路

  1. 使用alter table  test_order remove partitioning 清空之前所有的分区
  2. 使用新表和原表一样,建立新规划的分区。然后将旧表数据迁移到新表,删除旧表,将新表名称改为旧表

两者都可以实现这样的效果,具体可根据表数据量的大小自行选择方案

猜你喜欢

转载自blog.csdn.net/run_boy_2022/article/details/131738479