暂无图片
暂无图片
5
暂无图片
暂无图片
2
暂无图片

ORA-01555错误深度解析:从长事务到Undo优化的全面解决方案

原创 伟鹏 2025-03-20
242

最近从生产库恢复了一套数据库到测试环境,运行了一天,到第二天的时候,开发的同事反馈业务无法连接。我用sys用户测试能够正常连接,但是执行相关操作都会卡柱不动.最早因为有事儿没有跟着排查,只是重新做了一次恢复,今天问题复现,决定排查一下问题原因。查看日志发现有如下的信息

ORA-01555 caused by SQL statement below (SQL ID: ca0kuurgqgkq8, Query Duration=28991 sec, SCN: 0x0036.6a8f22fc): DELETE FROM **_ale***uence WHERE execution_time < '2025-03-19 02:00:02' Thu Mar 20 10:05:22 2025 Thread 1 advanced to log sequence 50 (LGWR switch) Current log# 10 seq# 50 mem# 0: /u01/app/oracle/oradata/ncdb/redo10.log Thu Mar 20 10:05:29 2025 Archived Log entry 157744 added for thread 1 sequence 49 ID 0xd9825ff2 dest 1: Thu Mar 20 10:07:36 2025 Thread 1 advanced to log sequence 51 (LGWR switch) Current log# 1 seq# 51 mem# 0: /u01/app/oracle/oradata/ncdb/redo01.log Thu Mar 20 10:07:39 2025 Archived Log entry 157745 added for thread 1 sequence 50 ID 0xd9825ff2 dest 1: Thu Mar 20 10:10:18 2025 Thread 1 advanced to log sequence 52 (LGWR switch) Current log# 2 seq# 52 mem# 0: /u01/app/oracle/oradata/ncdb/redo02.log Thu Mar 20 10:10:23 2025 Archived Log entry 157746 added for thread 1 sequence 51 ID 0xd9825ff2 dest 1: Thu Mar 20 10:13:53 2025 Thread 1 advanced to log sequence 53 (LGWR switch) Current log# 3 seq# 53 mem# 0: /u01/app/oracle/oradata/ncdb/redo03.log Thu Mar 20 10:13:58 2025 Archived Log entry 157747 added for thread 1 sequence 52 ID 0xd9825ff2 dest 1: Thu Mar 20 10:17:51 2025 Thread 1 cannot allocate new log, sequence 54 Checkpoint not complete Current log# 3 seq# 53 mem# 0: /u01/app/oracle/oradata/ncdb/redo03.log Thu Mar 20 10:26:29 2025 Thread 1 advanced to log sequence 54 (LGWR switch) Current log# 4 seq# 54 mem# 0: /u01/app/oracle/oradata/ncdb/redo04.log Thu Mar 20 10:26:36 2025
复制

从日志可以看出关键记录如下关键信息:

ORA-01555 caused by SQL: DELETE FROM **_ale***uence WHERE execution_time < '2025-03-19 02:00:02' (执行时间=28,991秒, SCN: 0x0036.6a8f22fc)
复制

该DELETE语句试图清理**_ale***uence表中两天前的数据,但执行时间长达‌8小时‌,最终因Undo数据被覆盖而失败。

ORA-01555是Oracle数据库中经典的“快照过旧”(Snapshot Too Old)错误,通常出现在长时间运行的查询或事务中。其本质是Oracle的读一致性机制无法找到足够的Undo数据来重建查询开始时的一致性视图。本文通过一个真实的运维案例,剖析该错误的成因,并提供系统的优化思路。

分析:为什么Undo数据会丢失?‌

1. 长事务的“蝴蝶效应”‌

事务时长与Undo占用正相关‌
单条DELETE操作扫描全表并逐行删除,产生大量Undo日志。Oracle的Undo表空间容量有限,若事务未及时提交,新事务会覆盖旧Undo段。
读一致性机制失效‌
其他会话在查询该表时,若需要访问被清理的数据版本,但对应的Undo已被覆盖,则触发ORA-01555。

2. 配置缺陷:Undo表空间的“三重困境”‌

容量不足‌:Undo表空间文件固定大小,未启用自动扩展。
保留策略失效‌:UNDO_RETENTION=900(默认15分钟),远低于8小时事务需求。
空间压力‌:高频DML操作(如批量插入)抢占Undo空间。

3. 索引缺失的全表扫描灾难‌

execution_time字段无索引,导致DELETE必须扫描全表。假设表有1亿行数据,实际需删除5000万行,全表扫描将产生至少5000万次Undo记录,远超Undo容量。

终结方案:从SQL优化到架构预防‌

1. SQL优化:化整为零的分批删除术‌

❌ 危险操作‌

DELETE FROM **_ale***uence WHERE execution_time < SYSDATE - 2; -- 全表扫描+长事务
复制

✅ 安全方案‌

BEGIN LOOP DELETE FROM pub_alertsequence WHERE execution_time < SYSDATE - 2 AND ROWNUM <= 5000; -- 每批删除5000行 EXIT WHEN SQL%ROWCOUNT = 0; COMMIT; -- 释放Undo段 DBMS_LOCK.SLEEP(1); -- 缓解锁争用 END LOOP; END;
复制

✏️ 设计要点‌

批处理‌:单次删除量需根据Undo空间动态调整(建议总Undo空间的5%~10%)。
休眠机制‌:避免高频提交导致日志刷新瓶颈。

2. Undo配置调优:空间与时间的平衡艺术‌

(1)扩容与自动扩展‌

ALTER TABLESPACE UNDOTS1 ADD DATAFILE '+DATA' SIZE 1G AUTOEXTEND ON NEXT 512M MAXSIZE UNLIMITED;
复制

(2)动态保留策略‌

sql
– 查询最长查询时间(单位:秒)
SELECT MAX(maxquerylen) FROM v$undostat;

– 设置UNDO_RETENTION
ALTER SYSTEM SET UNDO_RETENTION=3600; – 1小时

(3)监视Undo健康度‌

sql
Copy Code
SELECT TO_CHAR(begin_time, ‘YYYY-MM-DD HH24:MI’) AS begin_time,
undoblks,
maxquerylen
FROM v$undostat
ORDER BY begin_time DESC;

3. 索引设计:让数据定位提速100倍‌

为execution_time创建函数索引,加速范围扫描:

sql
Copy Code
CREATE INDEX idx_pub_alertsequence_etime ON pub_alertsequence(execution_time)
TABLESPACE indx;

执行计划对比‌

无索引‌:FULL TABLE SCAN + 排序
有索引‌:INDEX RANGE SCAN → 耗时从小时级降至分钟级

4. 预防体系:建立长效保护机制‌

SQL审核‌:禁止未分批次的大规模DELETE/UPDATE。
Undo监控告警‌:设置空间使用率>80%时触发预警。
定期索引维护‌:每月分析索引使用率,清理无效索引。

总结:ORA-01555的本质是资源博弈‌

ORA-01555并非单纯的配置错误,而是事务时长、Undo容量、数据访问模式的综合博弈结果。解决此类问题需遵循以下原则:

控制事务粒度‌:大事务拆分为可管理的小批次。
预留缓冲空间‌:Undo容量= (最大事务Undo量 × 2)。
查询路径优化‌:索引是减少Undo占用的最佳武器。

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

评论

暂无图片
4天前
评论
暂无图片 0
ORA-01555并非单纯的配置错误,而是事务时长、Undo容量、数据访问模式的综合博弈结果。解决此类问题需遵循以下原则: 控制事务粒度‌:大事务拆分为可管理的小批次。 预留缓冲空间‌:Undo容量= (最大事务Undo量 × 2)。 查询路径优化‌:索引是减少Undo占用的最佳武器。
4天前
暂无图片 点赞
评论
筱悦星辰
暂无图片
5天前
评论
暂无图片 0
不过度在意他人的看法,把时间和精力还给自己。
5天前
暂无图片 点赞
评论
伟鹏
关注
暂无图片
获得了1384次点赞
暂无图片
内容获得403次评论
暂无图片
获得了140次收藏
目录
  • 分析:为什么Undo数据会丢失?‌
    • 1. 长事务的“蝴蝶效应”‌
    • 2. 配置缺陷:Undo表空间的“三重困境”‌
    • 3. 索引缺失的全表扫描灾难‌
  • 终结方案:从SQL优化到架构预防‌
  • 1. SQL优化:化整为零的分批删除术‌
  • 2. Undo配置调优:空间与时间的平衡艺术‌
    • (1)扩容与自动扩展‌
    • (2)动态保留策略‌
    • (3)监视Undo健康度‌
  • 3. 索引设计:让数据定位提速100倍‌
  • 4. 预防体系:建立长效保护机制‌
  • 总结:ORA-01555的本质是资源博弈‌