并行dml在rac中默认不生效,根本原因是节点间事务上下文无法自动同步并行意图;必须显式启用、统一_parallel_cluster_cache_policy为adaptive、确保表空间管理方式合规、用户具parallel_dml权限、undo配置优化且私网无阻塞,缺一即退化串行。
并行dml在rac上默认不生效,必须显式启用且配合正确的undo配置,否则会退化为串行执行或触发大量gc和ges等待。
为什么ALTER SESSION ENABLE PARALLEL DML在RAC中常失效
根本原因不是语法错,而是RAC节点间事务上下文无法自动同步并行意图。即使会话启用了,若未满足以下全部条件,UPDATE /*+ PARALLEL(t,16) */仍走串行路径:
- 目标表所在表空间必须为
AUTOALLOCATE或UNIFORM(非SYSTEM管理方式) - 所有参与实例的
_parallel_cluster_cache_policy值需一致,推荐设为ADAPTIVE(非默认CLUSTER) - 执行用户必须有
PARALLEL_DML权限,且不能在FORALL内部隐式调用(需在外部会话级启用) - 若使用
ROWID批量更新,必须确保ROWID来源表与目标表位于同一实例缓存中,否则触发跨节点gc current block 2-way等待
undo表空间配置直接影响并行DML吞吐上限
RAC中每个实例独占自己的undo段,但并行DML可能跨节点修改数据,导致undo写入争用。常见错误是只扩容量,不调策略:
- 避免设置
undo_retention过高(如 > 3600),否则长事务阻塞undo段重用,引发enq: US - contention - 禁用自动调优:
ALTER SYSTEM SET "_undo_autotune" = FALSE SCOPE=SPFILE,防止AUM动态延长保留时间导致空间假性耗尽 - undo表空间数据文件必须分散到独立高速磁盘,且禁止与redo日志共盘——RAC中redo写入本身已通过私网广播放大IO压力
- 监控关键指标:
SELECT MAX(MAXQUERYLEN), MAX(TUNED_UNDORETENTION) FROM V$UNDOSTAT,若前者长期 > 1800 秒,说明存在未优化长查询拖累整个集群undo复用
gc_files_to_locks误配会放大并行DML的GES队列压力
当并行DML集中更新某几张大表时,gc_files_to_locks 配置不当会把全局锁争用从“文件级”恶化为“块级”,直接卡死GES队列:
- 先查当前值:
SHOW PARAMETER gc_files_to_locks,若返回*,说明启用自动计算,**不要手动覆盖** - 仅当
V$SEGMENT_STATISTICS显示某文件logical reads占比超 70% 且enq: HW - contention高发时,才考虑按文件指定,例如:ALTER SYSTEM SET gc_files_to_locks='5=800' SCOPE=SPFILE(文件号5分配800个全局锁) - 绝对禁止写成
'*=1000'或全文件统一调大——这会让GES进程忙于分发锁而非处理实际DML - 配合关闭DRM:
ALTER SYSTEM SET "_gc_policy_time" = 0 SCOPE=SPFILE,防止并行DML期间因资源重主(Remaster)引发短暂实例hang
真正卡住并行DML的往往不是CPU或SQL本身,而是undo段分配延迟、gc锁粒度失当、或私网带宽被大量小块block传输吃满。检查 V$SESSION_WAIT 中是否持续出现 gc cr block busy 或 ges global enqueue,比调优SQL执行计划更紧迫。











