oracle 11g 不支持在线拆分分区,仅 12c 及以上版本支持 alter table ... split partition ... online,需满足版本、事务、lob、全局索引、边界值及 default 分区等严格条件,并执行三重验证。

Oracle 11g 不支持在线拆分分区,ALTER TABLE ... SPLIT PARTITION 必然持有 AccessExclusiveLock,整个表在执行期间无法执行任何 INSERT/UPDATE/DELETE,连 ALTER TABLE ADD COLUMN 都会被阻塞。所谓“在线拆分”,只有 Oracle 12c(含)起才真正可行。
Oracle 12c+ 才支持真正的 ONLINE SPLIT
从 12c R2 开始,ALTER TABLE ... SPLIT PARTITION ... ONLINE 命令可用,它把排他锁降级为行级并发锁——应用侧 DML 不会阻塞,但前提是:
- 必须是 12c 或更高版本(11g 绝对不支持,强行加
ONLINE会报ORA-00922: missing or invalid option) - 目标分区不能有未提交的长事务(否则仍可能触发
ORA-00054,本质是其他会话占着锁,不是命令本身问题) - LOB 列需额外处理:含
CLOB/BLOB的分区不能直接ONLINE SPLIT,必须先MOVE LOB到新表空间,或拆成两步(先 offline split 再 move lob) - 全局索引必须显式指定
UPDATE GLOBAL INDEXES,否则依然失效;ONLINE只缓解锁,不绕过索引维护逻辑
拆分点必须严格落在原分区边界内
哪怕用了 ONLINE,AT 值越界仍直接报 ORA-14080。例如原分区 p_2023 定义为 VALUES LESS THAN (DATE'2024-01-01'):
-
AT (DATE'2023-07-01')✅ 合法(在[2023-01-01, 2024-01-01)内) -
AT (DATE'2022-12-01')❌ 报ORA-14080(低于下界) -
AT (DATE'2024-01-01')❌ 报ORA-14080(等于上界,不包含)
边界判断不能靠感觉,得查 USER_TAB_PARTITIONS 的 HIGH_VALUE 字段并解析,尤其注意 MAXVALUE 分区的隐含上界。
DEFAULT 分区含数据时,ONLINE 也救不了你
如果要拆的是 p_default(VALUES LESS THAN (MAXVALUE)),且 SELECT COUNT(*) FROM your_table PARTITION(p_default) 返回 > 0:
-
ONLINE仅降低锁级别,但数据移动本身仍需重写块、触发大量 I/O 和 buffer cache 压力 - 真实场景中常伴随
enq:TM-contention,尤其当并发 DML 活跃时 - 正确做法仍是先归档:用
INSERT /*+ APPEND */ INTO archive_table SELECT ... FROM your_table PARTITION(p_default) WHERE ...迁出旧数据,再对空p_default执行ONLINE SPLIT - 拆完后务必验证新分区名顺序:
INTO (PARTITION p_2023, PARTITION p_default)中,p_default必须保留为第二个分区,否则后续数据全进错地方
执行后必须立刻验证三件事
拆分完成不等于万事大吉,以下检查缺一不可:
- 查
USER_TAB_PARTITIONS确认新分区HIGH_VALUE正确,且NUM_ROWS非零(空分区会显示 0,但业务数据应归属明确) - 查
USER_INDEXES中全局索引的STATUS是否为VALID,ORPHANED_ENTRIES是否为NO(若为YES,说明异步维护未完成,需手动触发DBMS_PART.CLEANUP_GIDX) - 跑一条覆盖新旧边界的查询,比如
SELECT COUNT(*) FROM your_table WHERE partition_key BETWEEN DATE'2023-06-01' AND DATE'2023-08-01',确认结果与各分区NUM_ROWS总和一致
最容易被忽略的是索引状态验证——ONLINE 成功只代表语句没报错,不代表索引已就绪;一旦忽略,后续 DML 就会静默失败。











