帮你快速理解、总结文档立即下载

创建 INTERVAL RANGE 分区

最近更新时间:2026-08-20 15:23:31
我的收藏

概述

INTERVAL RANGE 分区是 RANGE 分区(含 RANGE COLUMNS)的增强能力。通过在建表或变更表时声明一个固定步长(INTERVAL),系统可以在 INSERT 写入超出现有分区范围的数据时,自动创建所需的新分区,无需人工或外部脚本定期执行 ALTER TABLE ... ADD PARTITION
该能力主要解决时间序列业务的运维痛点:使用普通 RANGE 分区时,如果忘记提前创建下一个时间段(或 ID 区间)的分区,INSERT 会直接报错 ER_NO_PARTITION_FOR_GIVEN_VALUE,导致业务写入中断。声明 INTERVAL 后,只要写入的值合法,正常情况下不会因为分区不存在而失败。
说明:
INTERVAL RANGE 分区是对标准 RANGE 分区语法的扩展,仅需在 PARTITION BY RANGE(...)PARTITION BY RANGE COLUMNS(...) 后追加 INTERVAL(...) 子句即可,无需改变现有分区表的使用方式。

前提条件

该功能自 V21.6.4.0 及以上版本开始支持,V21.6.4.0以下版本不支持声明 INTERVAL 分区。
系统变量 interval_partitioning_enabled 需为 ON(默认开启)。该变量关闭后,CREATE TABLE / ALTER TABLE 中的 INTERVAL 子句会直接报错,已有 INTERVAL 表的 INSERT 自动建分区功能也会被跳过(仅告警,不阻断写入,但越界数据会因分区不存在而报错)。
仅支持顶层 PARTITION BY RANGE(expr)PARTITION BY RANGE COLUMNS(column),且 RANGE COLUMNS 仅支持单列。LISTHASHKEY 分区不支持声明 INTERVAL。若为二级分区表,子分区必须是 HASH/KEY 类型。
建表时必须至少预定义1个初始分区。

语法

CREATE TABLE 时声明:
CREATE TABLE table_name (column_definitions)
PARTITION BY { RANGE(expr) | RANGE COLUMNS(column) }
INTERVAL({ interval_type, N | N })
(partition_definition [, partition_definition] ...);
对已有 RANGE 表追加或调整 INTERVAL(纯元数据操作,不涉及数据搬迁):
-- 追加或修改 INTERVAL 步长
ALTER TABLE table_name SET INTERVAL({ interval_type, N | N });

-- 清除 INTERVAL 属性,降级为普通 RANGE 表
ALTER TABLE table_name SET INTERVAL();

参数说明

参数
说明
interval_type
时间间隔类型,仅支持8种关键字:YEARQUARTERMONTHWEEKDAYHOURMINUTESECOND。仅用于 RANGE COLUMNS 且分区列为日期时间类型时。
N
间隔数值,必须为正整数常量,取值需 > 0(不支持子查询、列引用、变量)。时间类型为 SECOND 时,N 不能小于60。省略 interval_type 时按整数步长处理,仅适用于分区表达式为整数场景。
INTERVAL()
空括号,仅用于 ALTER TABLE SET INTERVAL(),表示清除已声明的 INTERVAL 属性。

分区列类型与 INTERVAL 类型的对应关系

分区列类型
支持的 INTERVAL 写法
INT/BIGINT/SMALLINT/TINYINT/MEDIUMINT(含 UNSIGNED)、RANGE(expr) 表达式
INTERVAL(N)(整数步长)
DATE
INTERVAL(YEAR, N)QUARTERMONTHWEEKDAY
TIME
INTERVAL(HOUR, N)MINUTESECOND
DATETIME
以上时间类型均支持
TIMESTAMPCHAR/VARCHAR/TEXT/BLOBENUM/SETDECIMAL/FLOAT/DOUBLE
不支持声明 INTERVAL。TIMESTAMP 类型可改用 PARTITION BY RANGE(UNIX_TIMESTAMP(ts)) INTERVAL(N)(此时 N 单位为秒,同样要求 ≥ 60)
注意:
生成列(GENERATED ALWAYS AS)、表达式默认值列(DEFAULT (expr))、AUTO_INCREMENT 列不能作为 INTERVAL 分区键。
分区键为函数表达式(如 RANGE(MONTH(dt)))时,声明的 N 不能超出该表达式的合理取值范围(例如 MONTH(dt) 的值域为1 ~ 12)。

系统变量

以下系统变量均为 GLOBAL 作用域,支持动态修改:
变量名
默认值
取值范围
说明
interval_partitioning_enabled
ON
ON/OFF
INTERVAL 分区功能总开关。关闭后拒绝新建 INTERVAL 声明,已有 INTERVAL 表的自动建分区能力也会被跳过。
interval_partitioning_support_auto_add_in_trx
ON
ON/OFF
控制显式事务(BEGIN/START TRANSACTION)中的 INSERT 是否允许触发自动建分区。关闭后,显式事务中的越界写入直接报 ER_NO_PARTITION_FOR_GIVEN_VALUE,需要在自动提交模式下写入。
interval_partitioning_support_duplicate_key_update
OFF
ON/OFF
控制 INSERT ... ON DUPLICATE KEY UPDATE 语句是否允许触发自动建分区。
interval_partitioning_max_auto_add_count
64
[1, 1024]
单次 INSERT 最多允许自动创建的分区数量,超过则整条 INSERT 失败(不会产生部分写入)。
interval_partitioning_max_auto_add_retries
5
[1, 60]
自动建分区过程中遇到锁等待超时等可重试的瞬态错误时,内部重试的次数上限。

使用限制

场景
行为说明
INSERT INTO t VALUES (...)(单行/多行)
越界值触发自动建分区
INSERT ... SELECT
不触发(写入值需执行期才能确定)
VALUES 中含标量子查询、存储过程参数、预处理占位符
不触发(非常量表达式无法提前计算应落入的分区)
INSERT ... ON DUPLICATE KEY UPDATE
interval_partitioning_support_duplicate_key_update 控制,默认关闭
INSERT IGNOREREPLACE
正常触发自动建分区
LOCK TABLES 模式下的 INSERT
跳过自动建分区(仅告警,不阻断,越界数据仍会报错)
触发器、存储函数内部的 INSERT
跳过自动建分区(仅告警)
显式事务中的 INSERT
interval_partitioning_support_auto_add_in_trx 控制,默认允许
写入值落在已有分区范围左侧(更小的值)
不会自动建分区,仅向后(更大方向)扩展
UPDATEDELETESELECT
均不触发自动建分区
单次 INSERT 触发的自动建分区数量不超过 interval_partitioning_max_auto_add_count(默认64),超出则整条语句失败,不会残留部分创建的分区。

自动分区命名规则

自动创建的分区统一以 _p 为前缀,后接边界值:
分区列类型
命名格式
示例
整数(INT/BIGINT 等)
_p<数值>
_p1000
DATE
_p<YYYYMMDD>
_p20260201
DATETIME
_p<YYYYMMDDhhmmss>
_p20260201000000
TIME
_p<hhmmss>
_p120000
注意:
手动创建分区时,如果分区名以 _p 开头,该名称必须与系统按当前边界值自动生成的名称完全一致,否则会报错拒绝建表或变更(错误信息为分区命名冲突)。建议手动分区统一不使用 _p 前缀,避免与自动命名冲突。

示例

示例1:整数步长——订单表按 ID 自动分区

分区键为整型,按1000为步长自动扩展。注意 AUTO_INCREMENT 列不能作为 INTERVAL 分区键,因为自增值在存储引擎内部分配,计算阶段不可知。
CREATE TABLE orders (
order_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
amount DECIMAL(10,2),
PRIMARY KEY (order_id)
)
PARTITION BY RANGE(order_id) INTERVAL(1000) (
PARTITION p0 VALUES LESS THAN (1000)
);

-- 写入超出现有分区范围的数据,触发自动建分区
INSERT INTO orders (order_id, user_id, amount) VALUES (2500, 1001, 99.90);

SHOW CREATE TABLE orders;
SHOW CREATE TABLE 输出中会以版本化注释 /*B!210604 INTERVAL(1000) */ 携带 INTERVAL 声明,并可见系统自动创建的 _p2000_p3000 等分区:
CREATE TABLE `orders` (
`order_id` bigint NOT NULL,
`user_id` bigint NOT NULL,
`amount` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`order_id`)
) ENGINE=ROCKSDB DEFAULT CHARSET=utf8mb4
/*!50100 PARTITION BY RANGE (`order_id`) */ /*B!210604 INTERVAL(1000) */ /*!50100
(PARTITION p0 VALUES LESS THAN (1000) ENGINE = ROCKSDB,
PARTITION _p2000 VALUES LESS THAN (2000) ENGINE = ROCKSDB,
PARTITION _p3000 VALUES LESS THAN (3000) ENGINE = ROCKSDB) */

示例2:按月自动分区——日志表按时间自动扩展

分区键为日期列,按月自动创建新分区,彻底免去每月手动 ADD PARTITION 的运维操作。
CREATE TABLE audit_logs (
log_id BIGINT NOT NULL,
content TEXT,
log_time DATE NOT NULL,
PRIMARY KEY (log_id, log_time)
)
PARTITION BY RANGE COLUMNS(log_time) INTERVAL(MONTH, 1) (
PARTITION p0 VALUES LESS THAN ('2026-02-01')
);

-- 写入 4 月的数据,系统自动补齐 2/3/4 月分区
INSERT INTO audit_logs (log_id, log_time) VALUES (1, '2026-04-15');

SELECT PARTITION_NAME, PARTITION_DESCRIPTION
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='audit_logs'
ORDER BY PARTITION_ORDINAL_POSITION;
INFORMATION_SCHEMA.PARTITIONS 中可以看到系统自动创建了 _p20260301_p20260401_p20260501 三个分区,覆盖到写入值所在的月份。

示例3:为已有 RANGE 表追加 INTERVAL 属性

对已经存在、未声明 INTERVAL 的 RANGE 表,可通过 ALTER TABLE ... SET INTERVAL(...) 追加该属性,该操作仅修改元数据,不涉及数据搬迁:
CREATE TABLE t_range (
id BIGINT NOT NULL PRIMARY KEY
) ENGINE=ROCKSDB
PARTITION BY RANGE(id) (
PARTITION p0 VALUES LESS THAN (1000)
);

-- 追加整数步长 100
ALTER TABLE t_range SET INTERVAL(100);

-- 后续 INSERT 越界值将自动建分区
INSERT INTO t_range VALUES (1050);

示例4:清除 INTERVAL 属性,降级为普通 RANGE 表

ALTER TABLE t_range SET INTERVAL();

SHOW CREATE TABLE t_range;

-- 清除后,越界写入将不再自动建分区,直接报错
INSERT INTO t_range VALUES (2000);
-- ERROR: Table has no partition for value 2000

常见问题

INTERVAL 分区和普通 RANGE 分区可以相互切换吗?

可以。对普通 RANGE 表执行 ALTER TABLE ... SET INTERVAL(...) 即可追加该属性;对 INTERVAL 表执行 ALTER TABLE ... SET INTERVAL()(空括号)即可清除该属性、降级为普通 RANGE 表。两个方向均为纯元数据操作,不涉及数据搬迁。

声明 INTERVAL 后,还需要用外部脚本定期 ADD PARTITION 吗?

不需要。只要写入的数据在有效取值范围内,系统会在 INSERT 时自动创建所需的分区。仍然可以手动执行 ALTER TABLE ... ADD PARTITION 提前创建分区,与自动建分区互不冲突。

自动创建分区的过程会影响 INSERT 的事务性吗?

自动建分区通过独立事务执行 DDL,DDL 提交后新分区即持久化、不可回滚;如果后续 INSERT 主体因唯一键冲突等原因失败,已创建的分区不会被撤销,后续写入仍可正常使用这些分区。

一次 INSERT 需要跨越很多个分区(例如迁移历史数据)会怎样?

单次 INSERT 自动创建的分区数不能超过 interval_partitioning_max_auto_add_count(默认 64),超过时整条语句失败,不会插入任何数据。如需一次性回补大量历史区间,建议提前通过 ALTER TABLE ... ADD PARTITION 手动分批创建分区,或调大该系统变量后再执行。

关闭 interval_partitioning_enabled 后,已有的 INTERVAL 表会怎样?

已有 INTERVAL 表的分区定义不受影响,SHOW CREATE TABLE 仍会显示 INTERVAL 声明。但该变量关闭期间,INSERT 越界数据不会再自动建分区(仅产生告警),需要手动执行 ADD PARTITION 补齐,或重新打开该变量。

相关文档