ALTER TABLE ... MOVE PARTITION ... ONLINE 并非真正无锁,需满足启用行移动、无未提交事务、存在主键或唯一索引、使用ROW STORE COMPRESS ADVANCED等硬性条件,否则仍会短暂阻塞DML或报错;MOVE后必须人工验证并重建局部/全局索引,否则导致查询异常。

ALTER TABLE ... MOVE PARTITION ... ONLINE 本身就不锁表——但“不锁表”是有严格前提的,不是加个 ONLINE 就万事大吉。实际执行中仍可能短暂阻塞 DML,甚至直接报错中断,关键看是否踩中那几个硬性条件。
为什么加了 ONLINE 还会锁表或失败
根本原因不是语法写错了,而是底层机制被卡住:MOVE PARTITION 在线操作依赖行移动(row movement)和索引可维护性,缺一不可。
-
ALTER TABLE t1 ENABLE ROW MOVEMENT必须提前执行,否则直接报ORA-14102 - 目标分区不能有未提交事务:查
V$TRANSACTION和V$SESSION,确认没人在该分区上做长事务 DML - 必须有主键或唯一索引:全局索引依赖它来定位行位置,缺失会导致索引重建失败或进入
UNUSABLE状态 - 别用
COMPRESS FOR OLTP:在线 MOVE 只认ROW STORE COMPRESS ADVANCED ONLINE,用错压缩类型会静默忽略或报错
MOVE 后索引状态必须人工验证
Oracle 声称“在线”,但局部索引不会自动重建,全局索引也可能变无效——这步漏掉,后续查询就可能走全表扫描或直接报 ORA-01502。
- 局部索引(LOCAL):必须显式重建对应分区,例如
ALTER INDEX idx_local REBUILD PARTITION p2 - 全局索引(GLOBAL):查
DBA_INDEXES.STATUS和DBA_IND_PARTITIONS.STATUS,确保全是VALID - 哪怕
UPDATE INDEXES ONLINE写在语句里,也不能替代状态检查——它只控制重建时机,不保证结果正确
真正影响业务连续性的隐藏点
所谓“在线”,是指支持并发 SELECT/INSERT/UPDATE/DELETE,但 MOVE 过程中会短暂持有 TX 锁(通常毫秒级)。问题在于:这个锁是行级还是段级?取决于你有没有启用 ROW MOVEMENT 和主键约束。
- 没主键或唯一索引 → 全局索引无法维护 → Oracle 退化为串行化处理 → 锁持续时间拉长,DML 明显排队
- LOB 列未单独处理 → 如果表含 LOB,MOVE PARTITION 不会动 LOB 段,后续插入可能触发
ORA-14647,必须拆成两步操作 - 大量小分区批量移动 → 别用循环逐个
MOVE PARTITION,锁窗口叠加风险高,应优先考虑DBMS_REDEFINITION替代
buffer busy waits(P3=4)或 RAC 下的 gc buffer busy acquire 混发,光看“锁表”就去调参数,大概率白忙。先分离等待类型,再动手。


















