adg只读库报ora-01555问题根源一定在主库,因备库不生成也不存储undo;必须同时满足三个条件:主库undo_retention设为v$undostat.maxquerylen的1.5倍以上、启用retention guarantee、undo表空间开启autoextend且空间充足。

ADG只读库报ORA-01555,问题一定在主库,备库本身不存UNDO,也无权调整UNDO策略。
查主库UNDO_RETENTION是否真生效
UNDO_RETENTION只是建议值,不加RETENTION GUARANTEE等于没设。常见错误是只改了参数却没启用保证机制:
- 执行
SELECT value FROM v$parameter WHERE name = 'undo_retention'确认值已生效(如设为3600) - 必须同步检查
SELECT tablespace_name, retention FROM dba_tablespaces WHERE tablespace_name = (SELECT value FROM v$parameter WHERE name = 'undo_tablespace')—— 若retention列返回NOGUARANTEE,说明配置无效 - 补上
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE(表空间名需与上一步一致)
验证主库UNDO表空间是否能自动扩展
即使启用了RETENTION GUARANTEE,若UNDO表空间无法扩容,Oracle会在空间满时直接报ORA-30036而非等待,但更常见的是:空间紧张→提前覆盖UNDO→备库查询失败。
- 运行
SELECT file_name, autoextensible, maxbytes/1024/1024 AS max_mb FROM dba_data_files WHERE tablespace_name = (SELECT value FROM v$parameter WHERE name = 'undo_tablespace') - 若
autoextensible为NO,立即执行ALTER DATABASE DATAFILE '/path/to/undotbs01.dbf' AUTOEXTEND ON NEXT 500M MAXSIZE 16G(路径必须与上一步结果严格一致) - RAC环境尤其要注意:所有节点共享同一UNDO表空间,不能只在单节点操作
看备库查询是否在“拖长一致性读窗口”
主库UNDO调优是治本,但备库侧的查询写法会显著放大风险——它不决定UNDO有没有,但决定“需要哪一段UNDO”。
- 避免在ADG上跑
SELECT * FROM huge_table这类无WHERE、无索引的全表扫描;执行时间越长,所需回溯的SCN越旧,撞上被覆盖UNDO的概率越高 - 禁用未绑定变量的SQL,硬解析+执行计划抖动会拉长CR链,加剧UNDO压力
- 对已知慢查询,可临时加
/*+ OPT_PARAM('_serial_direct_read' 'never') */防止跳过buffer cache中已有的CR块(仅缓解,非根治) - 更可靠的做法:用
DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER显式指定一个较新的SCN,把一致性读起点前移
最容易被忽略的点:12c+版本的INMEMORY影响
Oracle 12.1.0.2起,若主库启用了INMEMORY且涉及相关对象,其UNDO生成逻辑与传统行存储不同,部分场景下会导致tuned_undoretention低估实际需求。此时仅看v$undostat可能误判,必须结合SELECT * FROM v$im_segments确认是否有大表常驻IM列存储,并评估其DML频率对UNDO重用节奏的影响。











