interval分区不控制磁盘分布,仅按月自动建分区;数据存放到不同磁盘需手动为每个分区指定位于不同路径的表空间,初始分区必须显式定义tablespace及确定的values less than值。
oracle 的 interval 分区本身不直接控制数据存放到哪个磁盘,它只负责按月自动创建分区;真正决定“存储到不同磁盘”的是表空间(tablespace)及其底层数据文件(datafile)的物理位置。想让每月分区落在不同磁盘上,必须手动将每个新分区映射到预置的、位于不同存储路径的表空间——interval 分区不会自动帮你分配表空间,这一步必须显式干预。
建表时必须指定初始分区的表空间,且不能省略 PARTITION ... VALUES LESS THAN
Interval 分区依赖一个“锚点”分区启动,这个初始分区决定了后续所有自动分区的起点和默认表空间归属。如果建表时不指定表空间,Oracle 会用用户的 default tablespace,所有自动分区都会落到同一个地方。
-
VALUES LESS THAN必须是确定值,比如DATE'2024-01-01'或TO_DATE('2024-01-01', 'YYYY-MM-DD'),不能用SYSDATE或函数表达式 - 必须显式写
TABLESPACE ts_2024_jan,例如:CREATE TABLE sales ( id NUMBER, sale_date DATE ) PARTITION BY RANGE (sale_date) INTERVAL (NUMTOYMINTERVAL(1, 'MONTH')) ( PARTITION p_init VALUES LESS THAN (DATE'2024-01-01') TABLESPACE ts_2024_jan );
- 这个
p_init分区只是占位符,实际数据不会进这里(除非插入
每月分区落到不同磁盘,靠 ALTER TABLE ... MODIFY DEFAULT ATTRIBUTES
Interval 分区生成的新分区,默认继承初始分区的表空间。要让 2024-02 分区进 ts_2024_feb、2024-03 进 ts_2024_mar,必须在每次新分区生成前,提前修改表的默认属性——不是改已存在的分区,而是告诉 Oracle:“下一个自动分区,请用这个表空间”。
- 执行时机:在插入触发新分区之前,比如你预计下个月数据即将入库,就先运行:
ALTER TABLE sales MODIFY DEFAULT ATTRIBUTES TABLESPACE ts_2024_feb;
- 该语句只影响**尚未创建**的自动分区,对已存在的分区(包括
p_init和已生成的SYS_Pxxx)无影响 - 必须确保目标表空间已存在,且数据文件路径指向你想要的磁盘(如
'+DATA_DISK2/...'或/u02/oradata/...) - 无法“回溯”修改已生成分区的表空间——只能用
ALTER TABLE ... MOVE PARTITION ... TABLESPACE重建,这会产生锁和 I/O 开销
验证新分区是否真落到了目标磁盘
光看 USER_TAB_PARTITIONS 不够,得查数据文件物理路径才能确认是否跨磁盘。容易误判的是:表空间名相似(如 ts_2024_jan / ts_2024_feb)但底层 datafile 全在同一个 ASM diskgroup 或同一块 SATA 盘上,起不到 IO 分离效果。
- 查分区所在表空间:
SELECT partition_name, tablespace_name FROM user_tab_partitions WHERE table_name = 'SALES';
- 查表空间对应的数据文件路径:
SELECT file_name FROM dba_data_files WHERE tablespace_name = 'TS_2024_FEB';
- 对比多个表空间的
file_name,确认它们确实分布在不同物理设备(比如/dev/sdb1vs/dev/sdc1,或 ASM 中不同 failgroup) - 注意:
HIGH_VALUE是分区上限值,不是存储位置,别被它误导
最常被忽略的一点:Interval 分区的“自动”仅限于结构创建,不包含表空间调度、磁盘轮转、过期分区归档等运维动作。这些都得靠外部脚本或调度器(如 DBMS_SCHEDULER)在每月初主动执行 MODIFY DEFAULT ATTRIBUTES + 表空间预创建 + 权限校验,否则新分区永远只会躺在第一个表空间里。











