enq: US - contention 根本原因是_undo_autotune动态调优引发rollback segment频繁上下线,争抢dc_rollback_seg缓存latch;应禁用该参数并手动固定online undo段数量。
enq: us - contention 出现时,基本可以断定是 undo segment 分配环节卡住了——不是空间真不够,而是分配路径上出现了排队瓶颈。oracle 19c 默认启用的 _undo_autotune 隐含参数会动态调整 online undo segments 数量,但高并发 dml 下频繁 onlining/offlining 就会争抢 dc_rollback_seg 行缓存 latch,导致大量会话挂起在 us 队列里。
查清是不是 _undo_autotune 在捣鬼
先确认当前是否启用了自动调优,它才是 19c 中该等待事件高频爆发的“开关”:
- 执行
show parameter _undo_autotune—— 如果值为TRUE(默认),就是它在后台反复上线/下线 rollback segment - 查最近 1 小时内 undo segment 状态波动:
SELECT TO_CHAR(sample_time, 'HH24:MI'), COUNT(*) FROM v$undostat GROUP BY TO_CHAR(sample_time, 'HH24:MI') ORDER BY 1;如果分钟级 count 剧烈跳变(比如从 30 突然到 80 再跌回 20),说明 autotune 正在频繁干预 - 对比
v$rollname和v$rollstat:若usn数量远大于实际活跃事务数(v$transaction行数),且很多status是PENDING或刚从OFFLINE变成ONLINE,那基本坐实是 autotune 引发的震荡
紧急止血:禁用自动调优 + 手动稳住 undo 段数量
别等扩容或改 retention,先让分配逻辑“停下来”:
- 立即执行:
ALTER SYSTEM SET "_undo_autotune" = FALSE SCOPE=BOTH;注意这不是临时参数,需重启才生效的误解是错的,19c 中它支持SCOPE=BOTH动态生效 - 手动固定 online undo segments 数量:查当前在线段数
SELECT COUNT(*) FROM v$rollname WHERE status = 'ONLINE',再用ALTER ROLLBACK SEGMENT <name> ONLINE</name>/OFFLINE调整到一个稳定值(建议设为峰值事务数 × 1.5,但不超过 64) - 检查
v$undostat的maxquerylen和unxpstealcnt:如果后者持续 > 0,说明 active undo 正被偷用,此时UNDO_RETENTION设太低,需同步上调(但别盲目设成 18000 秒,先看最长查询耗时)
避免误判:别把空间不足当争用,也别把争用当空间不足
这两类问题现象相似但根因不同,处理方向完全相反:
-
dba_undo_extents中STATUS = 'ACTIVE'占比长期 > 30% 且UNEXPIRED接近 100%,大概率是空间真实紧张;这时加数据文件比调参数更直接 - 但若
ACTIVE很少、EXPIRED占大头,且v$session_wait里event = 'enq: US - contention'的p1text是name|mode、p1值反复出现相同高位字节(如 0x55000000),这就是典型的 enqueue 争用,和磁盘空间无关 - 执行
SELECT * FROM v$enqueue_stat WHERE eq_type = 'US',重点关注total_req#和total_wait#差值;如果差值小(比如只差几百),说明请求几乎全在等,不是资源耗尽而是锁路径慢
长期规避:绕过 autotune 但保留弹性能力
彻底关掉 _undo_autotune 后,不能靠拍脑袋定 undo 段数量。得用可验证的方式维持弹性:
- 用
ALTER SYSTEM SET UNDO_TABLESPACE = <ts_name></ts_name>显式绑定表空间,避免实例启动时选错 - 设置
RETENTION GUARANTEE要谨慎:ALTER TABLESPACE UNDOTBS RETENTION GUARANTEE会阻止 expired undo 被覆盖,反而加剧空间压力;只在明确需要 Flashback Query 且能保障空间余量时启用 - 监控重点转向
v$undostat的ssolderrcnt(snapshot too old 次数)和nospaceerrcnt(空间不足错误);前者高说明 retention 不够,后者高才说明真缺空间 - 压测期间务必开
AWR抓Top 5 Timed Events和Instance Activity Stats,重点关注undo segment相关 latch(row cache objects、enq: US - contention)与事务数的比率变化
真正难处理的不是参数开关本身,而是 autotune 关闭后如何让 DBA 对 undo 段数量的判断不依赖经验——必须用 v$undostat 的历史窗口数据反推,而不是看某一个快照。多数人栽在“以为调了参数就完事”,却漏掉了后续对 online segment 数量的主动盯控。


















