ORA-01555频发根本原因是UNDO_RETENTION与实际需求不匹配或Undo表空间过小导致旧块被提前覆盖;AWR中该参数仅为建议值,空间紧张时Oracle优先回收旧块。
Undo表空间被占满但事务未回滚,ORA-01555频发
根本原因不是undo“失效”,而是undo保留时间(undo_retention)与实际需求不匹配,或undo表空间过小导致旧undo块被提前覆盖。awr里undo_retention参数只是建议值,oracle只在自动管理(undo_management=auto)且表空间未满时尽力遵守;一旦空间吃紧,它会优先回收旧undo块——哪怕还没到保留时间。
实操建议:
- 检查当前配置:
SELECT name, value FROM v$parameter WHERE name IN ('undo_management', 'undo_retention', 'undo_tablespace'); - 确认Undo表空间是否为自动扩展:
SELECT file_name, bytes/1024/1024 AS mb, autoextensible FROM dba_data_files WHERE tablespace_name = (SELECT value FROM v$parameter WHERE name = 'undo_tablespace'); - 若
AUTOEXTENSIBLE=NO且空间使用率长期>85%,立刻扩容或启用自动扩展,否则ORA-01555无法根治
从AWR报告看Undo使用峰值和争用
AWR的“Undo Statistics”部分(非默认显示,需在生成报告时勾选)提供关键指标:每秒Undo块生成量(Undo blocks per sec)、事务平均Undo块数(Txn max query len)、最长查询持续时间(Max Qry Len (s))。这些直接决定所需UNDO_RETENTION下限。
实操建议:
- 用
awrrpt.sql生成指定时间段报告(如业务高峰2小时),重点关注“Undo Statistics”和“Instance Activity Stats”中undo change vector size(反映Undo写入压力) - 若
Txn max query len为1200秒(20分钟),则UNDO_RETENTION至少设为1200,否则长查询读取已覆盖的Undo块就会报ORA-01555 - 观察
SSOLDERRCNT(快照过旧错误次数)是否增长——这是Undo不足最直接的AWR证据
V$UNDOSTAT比AWR更细粒度定位问题时段
AWR每小时汇总一次,而V$UNDOSTAT保留最近1200次(默认)10秒采样点,能精确定位到分钟级Undo压力突增时刻,比如某批JOB启动后Undo块生成速率飙升3倍。
实操建议:
- 查最近2小时Undo压力:
SELECT begin_time, end_time, undoblks, txncount, ssolderrcnt, nospaceerrcnt FROM v$undostat WHERE begin_time > SYSDATE - 2/24 ORDER BY begin_time DESC; - 重点看
nospaceerrcnt > 0的时段——说明Undo表空间真的不够用,不是保留时间问题 - 对比同一时段的
v$session_longops,找执行时间长、读取大量块的SQL,它们是Undo消耗大户
为什么加大UNDO_RETENTION没用?
单纯调高UNDO_RETENTION却不扩容Undo表空间,等于给有限仓库贴更长的“勿动”标签——Oracle发现空间不够时,照样覆盖。真正起作用的是“可用空间 × 保留能力”的乘积。
实操建议:
- 计算理论最小Undo空间:
(Undo blocks per sec) × (UNDO_RETENTION) × (DB_BLOCK_SIZE),再加30%余量 - 生产环境Undo表空间建议独立、不共用,且初始大小不低于10GB(中小OLTP)或50GB(混合负载),避免碎片化
- 禁用
RETENTION GUARANTEE除非绝对必要——它强制保留,会导致空间耗尽时直接报ORA-30036而非降级处理
Undo问题从来不是单一参数能解决的,UNDO_RETENTION、表空间大小、自动扩展策略、长事务分布,四个点必须同步看。AWR只告诉你“哪里疼”,V$UNDOSTAT和V$TRANSACTION才帮你找到“哪颗牙坏了”。


















