ORA-01555在ADG备库的根源永远在主库;备库不生成UNDO,仅依赖主库传递的UNDO记录构造一致性读,故必须在主库同时满足:UNDO_RETENTION≥v$undostat.maxquerylen的1.5倍、启用RETENTION GUARANTEE、UNDO表空间AUTOEXTEND且空间充足。

ORA-01555在ADG备库上不是备库的问题
错误源头永远在主库。ADG备库不生成、不存储UNDO块,它只靠主库通过归档日志或实时传输传递过来的UNDO记录,构造一致性读(CR)块。一旦主库已将某个SCN对应的UNDO覆盖掉,而备库查询恰好需要那个时间点的数据版本,就必然报ORA-01555。查备库的v$undostat、调备库的UNDO_RETENTION、清buffer cache、重启实例,全无效。
主库必须同时满足三个硬性条件
只改一个参数等于没改。以下三项缺一不可,且需逐项验证是否真正生效:
-
UNDO_RETENTION设为v$undostat.maxquerylen的1.5倍以上(例如查出最大值是2200秒,至少设3600);执行ALTER SYSTEM SET UNDO_RETENTION = 3600 SCOPE=BOTH - 对应UNDO表空间启用
RETENTION GUARANTEE(如表空间名为undotbs1,执行ALTER TABLESPACE undotbs1 RETENTION GUARANTEE) - UNDO数据文件开启
AUTOEXTEND且MAXSIZE足够:用SELECT file_name, autoextensible, maxbytes/1024/1024 max_mb FROM dba_data_files WHERE tablespace_name = (SELECT value FROM v$parameter WHERE name = 'undo_tablespace')确认;若autoextensible为NO,立刻执行ALTER DATABASE DATAFILE '/u01/oradata/DB/undotbs01.dbf' AUTOEXTEND ON NEXT 100M MAXSIZE 10G
别信dba_free_space,要看真实UNDO压力
dba_free_space对UNDO表空间完全失真,它不统计UNEXPIRED块占用。真正要盯的是:
- 当前最长查询耗时:
SELECT MAX(maxquerylen) FROM v$undostat - UNDO空间是否被未过期块挤满:
SELECT tablespace_name, status, SUM(bytes)/1024/1024 mb FROM dba_undo_extents GROUP BY tablespace_name, status——若UNEXPIRED占比长期>95%,说明物理空间撑不住 - 是否出现
expstealcount > 0(从v$undostat查),这是Oracle被迫覆盖未过期UNDO的明确信号
DB Link跨库查询秒级报错另有原因
如果通过DB Link访问ADG备库,查询几秒就报ORA-01555,大概率不是UNDO配置问题,而是已知BUG:Bug 10018789(11.2.0.1–12.1)和其衍生Bug 10320455。该问题表现为:非ADG库通过DB Link连ADG备库时,即使主库UNDO配置完美,仍随机报错。Oracle官方修复方式是打补丁,或临时设置隐含参数:ALTER SYSTEM SET "_FIX_CONTROL" = "11814428:0" SCOPE=BOTH,然后重启实例。
最常被忽略的一点:开了RETENTION GUARANTEE但没开AUTOEXTEND,主库会很快报ORA-30036,这比ORA-01555更危险——它意味着UNDO段根本无法扩展,事务直接失败,而非仅查询失败。











