UNDO_RETENTION参数在undo表空间为固定尺寸且未启用RETENTION GUARANTEE时不起作用,此时Oracle优先保障新事务的undo需求,可能覆盖未达保留时间的undo数据。
undo_retention 不是“保修期”,而是数据库尝试保留 undo 数据的最短时间(单位:秒),实际能否保留住,取决于 undo 表空间是否有足够空间和是否启用了 retention guarantee。
undo_retention 参数改了但没生效?先看它是不是被覆盖了
修改 undo_retention 后查询仍显示旧值,常见原因有:
- 未用
ALTER SYSTEM SET undo_retention = 7200 SCOPE=BOTH;—— 缺少SCOPE=BOTH会导致仅内存生效,重启后丢失 - 数据库使用的是 PDB(多租户),需在对应 PDB 内执行
ALTER SYSTEM,CDB 级设置不继承 - 参数被 SPFILE 中的旧值锁定,检查是否误加了
COMMENT或拼写错误(如写成undo_retension) - Oracle 11g 启用自动调优后,
TUNED_UNDORETENTION视图值可能远高于你设的undo_retention,这是正常现象,表示系统根据最长运行查询动态延长了保留窗口
RETENTION GUARANTEE 到底要不要开?看业务场景
开启 RETENTION GUARANTEE 是把双刃剑,不是“更保险”就一定该开:
- 开:
ALTER TABLESPACE UNDOTBS1 RETENTION GUARANTEE;—— 数据库强制保留至少undo_retention秒的 undo,哪怕空间不足也会报ORA-30036(无法扩展 undo 表空间),事务直接失败 - 不开(默认):
NOGUARANTEE—— 空间紧张时,Oracle 会提前覆盖过期 undo,可能导致ORA-01555(快照过旧),尤其影响长查询或 Flashback Query - OLTP 系统通常不开,因事务短、并发高,空间压力大;DSS/报表类系统若依赖 Flashback 或长事务,可开,但必须同步确保 undo 表空间
AUTOEXTEND有合理MAXSIZE,避免无限膨胀
怎么确认当前 undo 保留策略真正在起作用?
别只信 show parameter undo_retention,要查运行时状态:
- 查表空间级保留策略:
SELECT tablespace_name, retention FROM dba_tablespaces WHERE contents = 'UNDO';—— 返回GUARANTEE或NOGUARANTEE - 查实际动态保留窗口:
SELECT tuned_undoretention FROM v$undostat ORDER BY begin_time DESC FETCH FIRST 1 ROW ONLY;—— 这才是 Oracle 当前“认为够用”的秒数 - 查 undo 空间压力:
SELECT MAX(maxquerylen), MAX(undoblks) FROM v$undostat;——maxquerylen超过undo_retention,说明有长查询在“倒逼”系统延长保留 - 查空间是否真够:
SELECT tablespace_name, round((free_space/total_space)*100, 2) AS pct_free FROM (SELECT tablespace_name, SUM(bytes) AS total_space, SUM(CASE WHEN status = 'EXPIRED' THEN bytes ELSE 0 END) AS free_space FROM dba_undo_extents GROUP BY tablespace_name);
真正难的不是改参数,而是判断 undo 表空间大小、undo_retention 值、是否开 GUARANTEE 这三者之间有没有形成死锁:比如开了 GUARANTEE 却没给表空间留足空间,或者 undo_retention 设得过大但业务根本不需要那么长的 Flashback 窗口。这些组合问题不会报错,只会慢慢拖垮性能或在某次大事务时突然崩出 ORA-30036。


















