alter table分区操作中仅truncate partition、exchange partition(with out validation)和move partition(无全局索引依赖且未启用update global indexes)可避免tm-x锁;其余如split/add/drop partition均触发全表x锁,阻塞所有dml及全表扫描。

ALTER TABLE分区操作会触发TM锁升级到X模式
Oracle对分区表执行ALTER TABLE ... SPLIT PARTITION、ADD PARTITION或DROP PARTITION时,不会只锁单个分区,而是默认将整个表的TM(Table Lock)从SS(Sub-Share)或SX(Sub-Exclusive)升级为X(Exclusive)模式。这意味着:其他会话哪怕只是执行SELECT /*+ FULL */全表扫描,也会被阻塞;DML操作(INSERT/UPDATE/DELETE)全部排队等待。
- 根本原因不是SQL本身,而是Oracle必须保证分区元数据一致性——比如
HIGH_VALUE边界值变更、PARTITION_POSITION重排、全局索引键范围校验等,都要求表级结构稳定 -
ONLINE关键字仅降低部分锁粒度(如避免阻塞某些DDL),但无法绕过TM-X锁;它不等于“无锁”,更不等于“不阻塞查询” - 即使目标分区当前为空(如
p_default),只要语句涉及分区定义变更,锁升级仍会发生
哪些ALTER TABLE分区操作实际不锁全表?
真正能规避TM-X锁的操作极少,且有严格前提:
-
TRUNCATE PARTITION:只重置HWM和segment header,全程保持SX锁,业务DML基本不受影响(但要注意后续ORPHANED_ENTRIES问题) -
EXCHANGE PARTITION(配合WITHOUT VALIDATION):若交换表结构完全一致、无约束冲突、且目标分区无未提交事务,则可维持SX锁级别 -
MOVE PARTITION:仅当该分区独立存在、无全局索引依赖、且未启用UPDATE GLOBAL INDEXES时,才可能避免全表X锁;否则仍需升级
如何验证当前锁状态而不依赖经验?
别猜,直接查v$lock和v$session组合视图:
SELECT s.sid, s.serial#, s.sql_id, l.type, l.lmode, l.request FROM v$lock l JOIN v$session s ON l.sid = s.sid WHERE l.type = 'TM' AND s.status = 'ACTIVE';
重点关注lmode = 6(即X锁)的记录;如果看到多个会话在等request = 6,说明已有ALTER TABLE分区操作持有了全表X锁。
真正容易被忽略的是:即使你只对一个子分区做SPLIT SUBPARTITION,只要该表定义了GLOBAL INDEX,Oracle仍可能因索引维护路径触发全表锁升级——这不是bug,是19c及以前版本的设计约束。











