何时选择间隔(Interval)分区

Interval Range分区是Range分区的扩展,在数据到达时自动创建间隔分区,不需要再手动创建新分区,方便了Range分区维护操作。

向RANGE分区表插入数据时,如果插入的数据超出当前已存在分区的范围,将无法插入并且会返回错误;而对于INTERVAL RANGE分区表,当新插入的数据超过现有分区的范围时,允许数据库自动创建新分区,根据INTERVAL子句指定的范围来新增分区。

如果分区范围设置为1个月,新插入的数据为当前转换点(当前存在的分区的最大边界值)两个月后的数据,将会创建该数据所在月份的分区,以及中间月份的分区。例如,您可以创建一个INTERVAL RANGE分区表,该表分区范围为1个月且当前的转换点为2021年9月15日。如果您尝试为2021年12月10日插入数据,那么将创建2021年9月15日至12月15日所需的3个分区,并将数据插入该分区。

下列情况下建议您使用间隔分区:

  • 数据按时间维度维护。

  • 维护滚动的数据窗口。

  • 不希望手动运维增加新的分区。

以下示例将orde_time作为分区键,按间隔划分sales表。创建Interval Range分区表需要一个初始的转换点,然后才能在转换点之外自动创建新的分区。

在数据库中创建一个新的Interval Range分区表,并向表中插入数据,示例如下:

CREATE TABLE sales
(
  id BIGINT,
  uid BIGINT,
  order_time DATETIME
)
PARTITION BY RANGE COLUMNS(order_time) INTERVAL(MONTH, 1)
(
  PARTITION p0 VALUES LESS THAN('2021-9-1')
);

在Interval Range分区表中插入数据,示例如下:

INSERT INTO sales VALUES(1, 1010101010, '2021-11-11');

插入数据后,通过SHOW CREATE TABLE查询sales表定义。新的表定义如下:

CREATE TABLE `sales` (
  `id` bigint(20) DEFAULT NULL,
  `uid` bigint(20) DEFAULT NULL,
  `order_time` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE  COLUMNS(order_time) */ /*!99990 800020200 INTERVAL(MONTH, 1) */
/*!50500 (PARTITION p0 VALUES LESS THAN ('2021-9-1') ENGINE = InnoDB,
 PARTITION _p20211001000000 VALUES LESS THAN ('2021-10-01 00:00:00') ENGINE = InnoDB,
 PARTITION _p20211101000000 VALUES LESS THAN ('2021-11-01 00:00:00') ENGINE = InnoDB,
 PARTITION _p20211201000000 VALUES LESS THAN ('2021-12-01 00:00:00') ENGINE = InnoDB) */

Interval Range分区自动新增加了_p20211001000000_p20211101000000_p20211201000000三个分区。

说明

_p作为前缀的分区名将会保留为系统命名规则,手动管理分区(创建新分区或者重命名分区的操作)时,将不允许使用此类型的分区名。例如,ADD PARTITIONREORGANIZE PARTITION操作将不允许使用‘_p’作为前缀的分区名;但是DROP PARTITION操作可以使用‘_p’作为前缀的分区名。

在这样的业务场景下,此前通常需要DBA在插入值触及转换点之前手动增加分区,但操作不当就有可能导致新的数据插入失败。通过创建Interval Range分区表,可以由系统自动增加分区,避免数据不能及时插入的问题。

由于分区数量最多只能达到8192,自动增加分区的数量也会受限制,可以配合分区表的生命周期管理解决方案使用,定期增加分区,同时定期将冷数据所在的分区自动迁移到OSS上。