暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Every Day of a DBA,第145期: ORA-01555 caused by SQL statement below

原创 ByteHouse 2026-06-29
94

作者:bytehouse Oracle ACE、PostgreSQL ACE
10+年数据库架构与运维实战经验
公众号:bytehouse
墨天轮专栏:bytehouse**
CSDN:Young DBA

一、故障基础信息

<msg time='2026-06-29T08:52:31.902+08:00' org_id='oracle' comp_id='rdbms'
 client_id='' type='UNKNOWN' level='16'
 host_id='sljj01' host_addr='92.236.125.207' module=''
 pid='3348'>
 <txt>ORA-01555 caused by SQL statement below (SQL ID: d3hhpucbn368y, Query Duration=1692 sec, SCN: 0x0001.f8361e97):
 </txt>
</msg>
<msg time='2026-06-29T08:52:56.176+08:00' org_id='oracle' comp_id='rdbms'
 client_id='' type='UNKNOWN' level='16'
 host_id='sljj01' host_addr='92.236.125.207' module=''
 pid='1260'>
 <txt>ORA-01555 caused by SQL statement below (SQL ID: g4u5hrwfkddn5, Query Duration=1710 sec, SCN: 0x0001.f8363c14):
 </txt>
</msg>

报错:ORA-01555 快照过旧
两条异常SQL_ID:

  1. d3hhpucbn368y,执行时长:1692s
  2. g4u5hrwfkddn5,执行时长:1710s

二、通过SQL_ID追溯语句与执行计划

1. 内存共享池抓取SQL文本

SELECT SQL_FULLTEXT FROM V$SQL WHERE SQL_ID = 'd3hhpucbn368y'; SELECT SQL_FULLTEXT FROM V$SQL WHERE SQL_ID = 'g4u5hrwfkddn5';

2. 抓取内存中执行计划

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('d3hhpucbn368y')); SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('g4u5hrwfkddn5'));

执行结果:游标不存在,子游标已被LRU回收。

3. AWR历史抓取SQL与执行计划

-- 历史SQL文本 SELECT SQL_TEXT,SQL_FULLTEXT FROM DBA_HIST_SQLTEXT WHERE SQL_ID IN ('d3hhpucbn368y','g4u5hrwfkddn5'); -- 历史执行计划 SELECT SQL_ID,OPERATION,OBJECT_NAME,OBJECT_OWNER FROM DBA_HIST_SQL_PLAN WHERE SQL_ID IN ('d3hhpucbn368y','g4u5hrwfkddn5'); -- AWR执行计划展示 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('d3hhpucbn368y')); SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('g4u5hrwfkddn5'));

4. ASH定位访问对象(可选)

SELECT DISTINCT CURRENT_OBJ# FROM DBA_HIST_ACTIVE_SESS_HISTORY WHERE SQL_ID IN ('d3hhpucbn368y','g4u5hrwfkddn5'); SELECT OWNER,OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_ID = &CURRENT_OBJ#;

5. 仅依靠SQL_ID定位数据表(无SQL文本时使用)

SELECT OBJECT_NAME TABLE_NAME FROM V$SQL_PLAN WHERE SQL_ID IN ('d3hhpucbn368y','g4u5hrwfkddn5') AND OPERATION = 'TABLE ACCESS';

三、排查受阻原因总结

  1. SQL执行完毕后,共享池游标被LRU算法自动清理,V$SQLV$SQL_PLAN无记录;
  2. 若故障时段未留存AWR快照,历史视图无法获取SQL文本、执行计划、访问表对象;
  3. 在内存视图+AWR全部失效的场景下,Alert日志中的原始SQL文本是本次故障唯一合法证据,排障不能只依赖SQL_ID。

四、分层根因分析

  1. 直接原因
    查询执行时长接近30分钟,远超undo_retention的回滚数据保留周期,大量业务DML反复覆盖UNDO回滚块,一致性读所需的数据镜像丢失,抛出ORA-01555。
  2. 核心根本原因
    SQL包含等值条件fwbh + 时间范围条件nwrksj,表上无匹配复合索引,语句执行全表扫描,扫描数据量过大,运行时间失控。
  3. 环境诱因
    业务高峰期日志频繁切换,事务产生量大,进一步加速UNDO段重用。

五、核查校验手段

(1)UNDO环境健康检查

-- 参数核查 show parameter undo_management; show parameter undo_retention; show parameter undo_tablespace; -- UNDO表空间与数据文件 SELECT tablespace_name,autoextensible,used_percent FROM dba_tablespace_usage_metrics JOIN dba_data_files USING(tablespace_name); -- 观测UNDO块消耗与事务量(故障时间段) SELECT begin_time,end_time,undoblks,txncount,tuned_undoretention FROM v$undostat ORDER BY end_time DESC;

判断标准:tuned_undoretention 自动调整值小于SQL执行时长,确认属于长查询引发的快照过旧。

(2)索引与执行路径核验

直接使用告警内原始SQL生成执行计划:

EXPLAIN PLAN FOR --粘贴alert日志内完整SQL SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

同时检查表现有索引:

SELECT index_name,column_name,column_position FROM dba_ind_columns WHERE table_name = 'RECG_DO_LOG' ORDER BY index_name,column_position;

(3)表统计信息检查

SELECT last_analyzed,num_rows,blocks FROM dba_tables WHERE table_name='RECG_DO_LOG';

(4)业务压力佐证:日志切换频次

SELECT first_time,sequence# FROM v$log_history WHERE first_time BETWEEN TO_DATE('2026-06-29 08:40:00','yyyy-mm-dd hh24:mi:ss') AND TO_DATE('2026-06-29 09:00:00','yyyy-mm-dd hh24:mi:ss');

六、解决方案

1)临时应急规避报错

-- 延长回滚保留时长 ALTER SYSTEM SET undo_retention=3600 SCOPE=BOTH; -- 确认UNDO数据文件开启自动扩展,禁止随意启用RETENTION GUARANTEE

2)治本优化

创建符合等值+范围规则的复合索引,等值列在前:

CREATE INDEX IDX_RECG_DO_LOG_FWBH_NWRKSJ ON RECG_DO_LOG(fwbh,nwrksj) ONLINE;

优化后SQL执行路径变为索引区间扫描,执行时间压缩至秒级,从根源消除ORA-01555。

3)长期优化

  1. 大表按nwrksj创建时间分区,缩小扫描范围;
  2. 报表任务调度至业务低峰期运行;
  3. 定期刷新表统计信息,防止优化器选错执行计划。

七、后续取证优化方案

  1. 缩短AWR快照采集间隔(15分钟),留存历史SQL与执行计划;
  2. 开启ASH历史采样,保障长查询可追溯;
  3. 运维排障双依据:优先使用SQL_ID追溯AWR,AWR缺失时以Alert日志SQL文本作为取证依据;
  4. 优化共享池游标留存,减少游标被快速回收:
ALTER SYSTEM SET cursor_sharing = EXACT SCOPE=BOTH; ALTER SYSTEM SET session_cached_cursors = 300 SCOPE=BOTH;

八、排障结论

本次ORA-01555为典型长查询一致性读失败。由于共享池游标已被LRU回收,且无对应AWR历史数据,无法仅依靠SQL_ID获取执行计划。依托Alert日志中的SQL谓词判定:语句缺少(fwbh,nwrksj)复合索引,造成全表扫描,SQL运行时长高达近30分钟,超出UNDO数据保留窗口,最终触发快照过旧。通过创建匹配复合索引缩短执行耗时,可彻底解决该故障。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论