执行分区交换前必须确认5个前提:列定义完全一致;源表无任何约束(含disabled);索引须全部drop;目标分区必须为空;两表tablespace须同为local管理。
分区交换前必须确认的5个前提条件
直接跑 exchange partition 脚本却卡住或报错,90% 是因为前置校验没做全。oracle 不会主动告诉你“为什么不能换”,只会抛 ora-14097 或静默失败。
-
源表和目标分区表的列名、顺序、数据类型(含精度/长度)、空值约束必须完全一致;VARCHAR2(50)和VARCHAR2(50 CHAR)算不一致 - 源表不能有主键、唯一约束、外键 —— 即使是 DISABLED 状态也不行,必须
DROP - 源表索引必须全部
DROP(不是DISABLE),否则交换后索引状态异常,后续 DML 可能报ORA-01502 - 目标表的待交换分区不能是
EMPTY以外的状态:如果该分区已有数据,需先TRUNCATE PARTITION或DROP - 两个表的
TABLESPACE必须在同一个EXTENT MANAGEMENT LOCAL类型下;若一个是 ASSM、一个是 MANUAL,交换会失败
LOAD阶段用外部表 + 并行 INSERT APPEND 替代 SQL*Loader
传统 sqlldr 控制文件方式在 11g 中已非最优:它无法与分区交换流程无缝衔接,且错误日志分散、重试成本高。改用外部表 + INSERT /*+ APPEND PARALLEL(n) */ 更可控。
- 建外部表时指定
REJECT LIMIT UNLIMITED,并在PREPROCESSOR中用 shell 脚本预检文件编码和字段分隔符,避免运行中因乱码中断 -
INSERT必须加/*+ APPEND */提示,否则走常规路径,Redo 暴涨且无法触发直接路径写入 - 并行度建议设为
min(CPU_COUNT, 8);超过 8 常引发enq: KO - fast object checkpoint等争用 - 源数据文件名建议带时间戳(如
data_20260604.csv),外部表定义中用LOCATION ('data_20260604.csv')显式绑定,防止误读旧文件
EXCHANGE PARTITION 必须加 VALIDATION 或 WITHOUT VALIDATION?
默认 EXCHANGE PARTITION 会做全局索引一致性校验,对大表可能耗时数分钟甚至锁表。但盲目加 WITHOUT VALIDATION 会埋雷:后续查询若走全局索引,可能返回错误结果。
- 如果目标表只有本地索引(
LOCAL),可安全使用WITHOUT VALIDATION—— 本地索引不跨分区,交换不影响结构 - 若有全局索引,且你确认源表数据完全符合分区键范围(例如源表
WHERE dt BETWEEN DATE '2026-06-01' AND DATE '2026-06-30'),可用UPDATE GLOBAL INDEXES替代校验,它只更新索引元数据,不扫数据 - 禁用校验后,首次查询该分区前务必手动执行
ANALYZE TABLE ... VALIDATE STRUCTURE CASCADE,否则ORA-08102可能在半夜出现
滚动窗口场景下,ADD + DROP 分区要避开高峰时段
很多脚本把 ALTER TABLE ... ADD PARTITION 和 ALTER TABLE ... DROP PARTITION 写在一起执行,看似原子,实则两步都涉及数据字典更新和段头块修改,在高并发 OLTP 环境下极易引发 library cache lock。
-
DROP PARTITION推荐用UPDATE INDEXES选项(如有全局索引),否则索引失效需重建,耗时不可控 -
ADD PARTITION边界必须用TO_DATE字面量,严禁ADD_MONTHS(SYSDATE, 1)—— DDL 解析时不求值,下次执行可能越界报ORA-14400 - 关键点:这两条语句之间不要
COMMIT;它们本身是 DDL,隐式提交,强行拆开反而增加风险 - 真正要避开的是
EXCHANGE和DROP的时间重叠 —— 前者锁分区,后者锁整个表头,同时跑会死锁
最易被忽略的是统计信息同步:交换完成后,DBA_TAB_STATISTICS 里原分区的 NUM_ROWS 会清零,但新数据实际已就位。不立刻收集该分区统计信息,优化器大概率选错执行计划,尤其当关联其他大表时。











