undo_retention 是 oracle 尽可能保留 undo 数据的目标时长(秒),非最小保证值;其合理设置需结合 v$undostat 的 maxquerylen 和 undo 块生成速率,并确保 undo 表空间容量充足、关闭 _undo_autotune 且必要时启用 retention guarantee。
undo_retention 不是“最小保留时间”,而是 oracle 尽可能保留 undo 数据的目标时长(秒)。它不保证一定能撑满这个时间,实际能否保留住,取决于 undo 表空间是否够用、是否有未提交事务占着空间、以及是否启用了 _undo_autotune。
UNDO_RETENTION 值设多少才合理
- OLTP 系统通常设为
900(15 分钟)到3600(1 小时) - 混合负载建议
3600~7200(2 小时) - 若需支持闪回查询(如
AS OF TIMESTAMP),至少设为86400(24 小时) - Oracle 19c RAC 实践中常见设为
21600(6 小时),但前提是 undo 表空间容量已按此预留
关键判断依据不是“想留多久”,而是:
- 查看历史最长查询运行时长:
MAXQUERYLEN字段来自v$undostat - 查看高峰期每秒生成 undo 块数:
MAX(undoblks / ((end_time - begin_time)<em>24</em>3600)) - 结合
db_block_size计算理论所需空间,再反推可安全设置的UNDO_RETENTION
关闭自动调优才能让 UNDO_RETENTION 生效
Oracle 11g 起默认开启 _undo_autotune(值为 TRUE),它会动态压低 UNDO_RETENTION,哪怕你显式设了 21600,也可能被自动降为几百秒 —— 这是 ORA-01555 频发却查不到原因的常见根源。
必须执行:
ALTER SYSTEM SET "_undo_autotune" = FALSE SCOPE=BOTH SID='*';
注意:
- 该参数修改后立即生效,无需重启
- 不能只在单个实例改(RAC 环境下要加
SID='*') - 改完立刻查
v$parameter确认值为FALSE,别信文档说的“默认 false”
启用 RETENTION GUARANTEE 才真能“保底”
即使关了自动调优,只要 undo 表空间紧张,Oracle 仍可能覆盖 UNDO_RETENTION 内的未过期 undo 块(状态为 UNEXPIRED),导致闪回失败或 ORA-01555。
要真正锁定保留底线,得对 undo 表空间启用保障:
ALTER TABLESPACE UNDOTBS1 RETENTION GUARANTEE;
但要注意:
- 启用后,若空间不足,新事务可能直接报
ORA-30036(无法扩展 undo 段),而不是悄悄覆盖旧数据 - 必须配合足够大的表空间容量,否则等于主动制造阻塞
- 可随时关闭:
ALTER TABLESPACE UNDOTBS1 RETENTION NOGUARANTEE;
容量没跟上,UNDO_RETENTION 再大也没用
很多 DBA 把 UNDO_RETENTION 从 900 改成 86400,结果第二天就爆 ORA-01555,根本原因是没同步扩容 undo 表空间。
典型误操作:
- 只改参数,不查
v$undostat的undoblks峰值 - 忽略
db_block_size(常为 8192,但有些库是 16K 或 32K) - 用
dba_free_space看“空闲”就以为够用,其实大量UNEXPIRED块占着不动,真实可用空间远低于显示值
最稳妥做法:
- 先跑一周
v$undostat,取MAX(undoblks)和对应时段的MAXQUERYLEN - 按公式算出最低需求:
UNDO_RETENTION × 每秒最大 undo 块数 × db_block_size - 新增数据文件时,别只
AUTOEXTEND ON,先给足初始大小(比如 2G 起步),避免频繁扩展引发争用
真正卡住 undo 保留能力的,从来不是参数本身,而是磁盘上那几块文件有没有被喂饱。











