开启\_RETENTION GUARANTEE可强制保留未过期undo数据,但需配合足够大的UNDO_RETENTION值和充足的undo表空间,否则仍会报ORA-01555或ORA-30036;该隐含参数须重启实例生效,且仅在自动管理undo模式下有效。
开启 _RETENTION GUARANTEE 会强制保留 undo 数据,但不是万能保险
这个参数的作用很直接:一旦启用,oracle 就不会因为空间压力而覆盖那些还没过期的 undo 数据块,哪怕 undo 表空间快满了、其他事务在等空间,也会报 ora-30036 而不是悄悄覆盖。但它不保证你一定能闪回查询到某条记录——前提是你得有足够长的 undo_retention 设置,且 undo 表空间本身够大。
常见错误现象:FLASHBACK QUERY 突然报 ORA-01555: snapshot too old,查了 UNDO_RETENTION 是 1800 秒,结果发现 undo 表空间太小、数据被提前重用——这时候开 _RETENTION GUARANTEE 才可能起作用。
- 它只对「未过期」的 undo 数据生效(即仍在
UNDO_RETENTION时间窗口内) - 必须配合自动管理的 undo 表空间(
UNDO_MANAGEMENT = AUTO),手工管理下无效 - 开启后,如果空间不足,新事务可能直接失败,而不是降级容忍;监控
v$undostat的unxpstealcnt和ssolderrcnt很关键
_RETENTION GUARANTEE 是隐含参数,不能用 ALTER SYSTEM SET 直接改
它不属于公开参数,没有文档支持的动态修改方式。想启用或关闭,必须写进初始化参数文件(pfile 或 spfile),然后重启实例。在线修改会报 ORA-02095:specified initialization parameter cannot be modified。
使用场景:通常只在明确需要强一致性闪回(比如审计系统依赖闪回查询做变更比对)、且能接受事务失败风险时启用。
- 启用方式:
ALTER SYSTEM SET "_retention_guarantee"=TRUE SCOPE=SPFILE;,再重启 - 关闭方式同理,设为
FALSE,也必须重启才生效 - 检查是否生效:
SELECT ksppinm, ksppstvl FROM x$ksppi JOIN x$ksppcv USING (indx) WHERE ksppinm = '_retention_guarantee';
开启后空间压力会立刻暴露,UNDO_TABLESPACE 大小必须重新评估
原来靠“悄悄覆盖”撑住的负载,开启后会变成硬性空间需求。undo 表空间不再能“弹性压缩”,而是按峰值活跃事务量 × 最大单事务 undo 生成量 × UNDO_RETENTION 时间来刚性估算。
性能影响明显:高并发 DML 场景下,undo 表空间扩容不及时,ORA-30036 出现频率会上升,应用层需处理这类失败(比如重试或降级)。
- 别只看
DBA_UNDO_EXTENTS的STATUS,重点盯v$undostat的maxquerylen(最长查询时间)和unxpstealcnt(被迫偷用已提交 undo 次数) - 如果
unxpstealcnt > 0且开了_RETENTION_GUARANTEE,说明空间已经不够,必须扩容 undo 表空间 - 扩容建议:先加 20%~30%,观察一周
v$undostat中nospaceerrcnt是否归零
和 UNDO_RETENTION 配合才有意义,单独开没用
_RETENTION GUARANTEE 不决定“保留多久”,它只决定“到了这个时间前,绝不删”。真正控制时间窗口的是 UNDO_RETENTION(单位秒)。如果后者设成 900,那即使开了 guarantee,900 秒一过,数据照样可被覆盖。
容易踩的坑:有人以为开了 guarantee 就能无限闪回到任意时间点,结果发现 10 分钟前的查询就报 ORA-01555——大概率是 UNDO_RETENTION 本身设得太短,或者实际 undo 生成量远超预期,导致空间撑不住那么久。
- 查当前设置:
SHOW PARAMETER UNDO_RETENTION - 生产环境建议最小值:至少大于最长运行查询的执行时间(查
v$sql中elapsed_time/1000000的最大值) - 如果业务有定时批处理,且批处理里包含长事务,
UNDO_RETENTION必须覆盖整个批处理周期,否则 guarantee 也救不了
真正难的不是开这个参数,而是预估 undo 空间压力和事务行为之间的匹配度。很多问题爆发时,其实 v$undostat 早就有预警信号,只是没被持续采集和分析。










