undo块传输等待本质是rac跨实例事务一致性保障,因本地实例需从远端获取undo块构造cr块而触发cache fusion全局缓存请求与等待。
undo块传输等待的本质是跨实例事务一致性保障
oracle rac中出现大量undo块传输等待(如 gc cr block、gc current block 伴随undo段访问,或间接表现为 enq: us - contention、latch: row cache objects (dc_rollback_segments)),根本原因不是undo本身被“传输”,而是当一个实例需要读取另一个实例生成的undo数据(例如做一致性读cr块构造)时,必须通过cache fusion从远端实例拉取对应undo块——这个过程触发全局缓存请求和等待。
哪些操作会高频触发Undo相关块跨实例传输
不是所有Undo访问都引发RAC间传输。关键在于“谁在读、读什么、从哪来”:
- 本地实例执行查询,需构造CR块,而该块对应的Undo头(
undo segment header)或Undo数据块(undo block)当前只缓存在远端实例Buffer Cache中 → 触发gc cr block等待 - 远端实例刚提交事务,LGWR尚未完成写入,本地实例因一致性读急需其Undo信息 → LMS需协调获取并克隆,可能卡在
gc current block 2-way - 高并发DML集中在同一Undo表空间,且该表空间的回滚段(
rollback segment)由某单一实例“主控”(master),其他实例频繁申请分配/访问 → 触发enq: US - contention - UNDO表空间数据文件自动扩展(
autoextend on)时,资源字典更新需广播到所有节点,争用row cache objectslatch → 表现为latch: row cache objects (dc_rollback_segments)
参数与配置不当会放大Undo传输压力
很多DBA只调 undo_retention,却忽略底层RAC协同机制对Undo路径的影响:
-
_rollback_segment_count过小(尤其RAC多节点场景):默认值可能仅几十,导致回滚段集中争用;建议设为固定较大值(如6000),避免动态分配瓶颈 -
undo_tablespace在各节点未统一配置:比如节点1用UNDOTBS1,节点2仍用默认UNDOTBS2,造成回滚段分布不均,主控实例成为热点 -
db_block_size×db_file_multiblock_read_count过大:全表扫描时CR块构造需大量Undo块,单次请求数据量激增,UDP缓冲区溢出 → 加重gc cr multi block request,间接拖慢Undo相关块获取 - 私网带宽不足或UDP参数过小:AIX上
udp_recvspace
真正要盯住的是“谁在等、等哪个Undo块”
直接查 v$active_session_history 比看AWR更及时:
SELECT event, p1, p2, p3, sql_id, blocking_session FROM v$active_session_history WHERE event LIKE 'gc%' AND sample_time > SYSDATE - 1/24/60 AND session_state = 'WAITING';
拿到 p1(file#)和 p2(block#)后,反查是否属于Undo表空间:
SELECT tablespace_name, segment_name, segment_type FROM dba_extents WHERE file_id = &p1 AND &p2 BETWEEN block_id AND block_id + blocks - 1;
若确认是Undo段头或Undo数据块,再结合 v$rollstat 和 gv$transaction 定位长事务或未提交会话——这才是根因。盲目扩容Undo表空间或调高 undo_retention 只会让问题更隐蔽。











