ORA-01555系列:一、ORA-01555错误的本质与原理
我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。
在之前的文章中发过几篇关于ORA-00704、ORA-00604、ORA-01555错误的分析和处理,部分小伙伴觉得这种场景在工作遇得比较少,希望多发一点关于常规场景中ORA-01555错误的分析和处理,今天我们就开一个简单的系列,来简单的说明一下ORA-01555的说明、常见的场景和解决方案,本文章是一个系列文章,计划用三章来写。下面进入正题。
1.1 ORA-01555错误的本质与原理
1.1.1 错误定义
ORA-01555(Snapshot too old)是Oracle数据库中最常见的错误之一,报错信息通常为:
ORA-01555: snapshot too old: rollback segment number with name "" too small
该错误的本质是:查询过程中需要的数据快照(旧版本)已经被覆盖或回收,无法保证一致性读。这与Oracle的多版本并发控制(MVCC)机制密切相关。
1.1.2 一致性读与UNDO/回滚段
Oracle通过UNDO(或早期的回滚段)来实现一致性读(除LOB特殊字段外)。当一个查询开始时,Oracle会为其创建一个一致性快照。若查询期间有DML操作(如UPDATE/DELETE),Oracle会将被修改的数据的旧版本写入UNDO表空间。查询需要访问这些旧版本时,就会去UNDO中查找。
关键点:
- 查询本身不写UNDO,只有DML操作才会写UNDO。
- 查询需要的UNDO是DML操作产生的,而不是查询自己产生的。
- 如果UNDO中的旧数据被覆盖或回收,查询就无法获得一致性快照,从而报ORA-01555。
1.1.3 触发机制与误区
触发机制
- 查询持续时间超过UNDO_RETENTION,导致所需UNDO被覆盖。
- UNDO表空间空间不足,Oracle“偷用”未过期的UNDO块(空间压力下的“steal”机制)。
- LOB字段的PCTVERSION/RETENTION设置不合理,导致LOB历史记录被覆盖。
- 并发DML与查询冲突,UNDO空间压力大。
- 罕见情况下,Oracle内部BUG也可能导致ORA-01555。
- 特殊情况下无法在UNDO表空间中查询到UNDO段记录或者UNDO不可访问等。
常见误区
- 误区1:为查询session指定大回滚段能避免ORA-01555。实际上,查询本身不写UNDO,指定大回滚段无效。
- 误区2:增大rollback segment的maxextents参数能解决问题。实际上,回滚段扩展只在有未提交事务时才会发生,ORA-01555的本质是已提交事务的UNDO被覆盖。
- 误区3:只有大表才会出现ORA-01555。实际上,任何表、任何查询,只要UNDO空间不足或查询时间过长,都可能遇到。
1.1.4 ORA-01555的详细触发流程(官方案例还原)
以官方文档(Mosid:467872.1)中的时序为例:
- Session #1开始查询表A。
- Session #2更新表A的某行X。
- Session #1查询到X,发现X被更新过,需要去UNDO中找旧版本。
- Session #2继续更新表A的Y并提交,释放了事务槽。
- Session #2又更新表B的Z并提交,因UNDO空间压力,Y的UNDO被覆盖。
- Session #1查询到Y时,发现需要的UNDO已被覆盖,报ORA-01555。
结论:
只要查询期间需要的UNDO被覆盖,无论是因为空间压力还是查询时间过长,都会触发ORA-01555。
1.2 ORA-01555的常见触发场景与案例
1.2.1 长事务/长查询
场景描述:
长时间运行的查询(如全表扫描、复杂报表、数据同步等)极易触发ORA-01555。查询开始时创建的快照需要一直保留到查询结束,期间有大量DML操作,UNDO空间中的旧数据很快被覆盖。
案例1:报表查询导致ORA-01555
某公司有一张大表SALES,每晚跑全表扫描报表,需2小时。白天有大量销售数据写入。报表查询期间,UNDO空间被持续消耗,导致ORA-01555。
案例2:游标慢fetch导致ORA-01555
某应用采用open cursor后慢慢fetch数据,fetch过程中有大量DML操作,导致需要的UNDO被覆盖,fetch到一半报ORA-01555。
1.2.2 大量DML操作导致UNDO空间被覆盖
场景描述:
即使查询本身不长,若期间有大批量DML操作(如批量更新/删除),也会导致UNDO空间迅速被消耗,覆盖旧版本数据。
案例3:批量更新导致ORA-01555
某电商平台凌晨批量更新订单状态,涉及百万数据。定时任务查询订单表时,因UNDO空间被批量DML消耗,查询需要的旧数据被覆盖,报ORA-01555。
案例4:循环提交导致ORA-01555
某应用在循环中每处理一条数据就commit,导致UNDO空间被频繁回收,其他查询需要的UNDO很快被覆盖,频繁报ORA-01555。
1.2.3 UNDO表空间配置不合理
场景描述:
UNDO表空间过小,或参数设置不合理,导致UNDO无法保留足够历史数据。
案例5:UNDO表空间过小
某企业数据库迁移后,UNDO表空间未扩容,业务量大增,DML频繁,UNDO空间很快用完。复杂查询频繁遇到ORA-01555。扩容UNDO表空间后问题解决。
1.2.4 并发查询与DML操作冲突
场景描述:
高并发环境下,多个查询和DML操作同时进行,UNDO空间竞争激烈,易引发ORA-01555。
案例6:并发操作导致ORA-01555
某金融系统月末结算时,多个批量任务并发执行,包括大批量插入、更新和查询。UNDO空间有限,部分查询任务需要的旧数据被覆盖,报ORA-01555。
1.2.5 LOB字段相关的ORA-01555
场景描述:
LOB字段的快照管理与普通数据不同,PCTVERSION/RETENTION设置不合理时,频繁更新LOB字段会导致快照丢失,报ORA-01555。
案例7:LOB字段快照丢失
某系统频繁更新含有LOB字段的大表,PCTVERSION设置过小,导致查询时无法获取旧版本LOB数据,报ORA-01555。
1.2.6 罕见的BUG或特殊场景
场景描述:
如MosID:467872.1所述,某些Oracle版本下,BUG可能导致即使查询时间为0秒也报ORA-01555。
案例8:BUG导致ORA-01555
某客户数据库在查询duration为0秒时也报ORA-01555,经查为Oracle内部BUG,需打补丁或升级版本。
1.3 ORA-01555的影响与诊断
1.3.1 对业务的影响
- 查询失败,影响报表、统计、数据同步等业务。
- 频繁报错影响系统稳定性和用户体验。
- 可能导致数据一致性风险,影响业务决策。
1.3.2 诊断ORA-01555
详细诊断步骤:
收集报错信息
- 用户端/客户端的ORA-01555报错信息。
- 数据库alert log中的ORA-01555详细信息(包括SQL、UNDO段名、查询持续时间等)。
分析UNDO使用情况
- 查询V$UNDOSTAT、DBA_UNDO_EXTENTS,分析UNDO空间使用、回收、被“偷用”情况。
- 重点关注UNXPSTEALCNT(被偷用的未过期UNDO块数)、EXPSTEALCNT(被重用的已过期UNDO块数)、SSOLDERRCNT(ORA-01555错误数)。
分析SQL执行计划和事务持续时间
- 检查SQL是否存在全表扫描、长时间未结束的事务。
- 检查应用是否存在慢fetch、循环commit等问题。
检查LOB字段的PCTVERSION/RETENTION设置
- 查询DBA_LOBS,确认LOB字段的快照管理参数是否合理。
排查BUG
- 若排查无果,结合Oracle MOS文档,确认是否为已知BUG。
------------------作者介绍-----------------------
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)

ORA-01555系列:一、ORA-01555错误的本质与原理的更多相关文章
- RAC安装gird,第一个节点执行root.sh报"The ora.asm resource is not ONLINE"错误
RAC版本:11.2.0.4 OS版本:linux 6.4 RAC安装gird,第一个节点执行root.sh运行失败,报"The ora.asm resource is not ONLINE ...
- Oracle启动中,spfile.ora、init<SID>.ora、spfile<SID>.ora 这三个文件正确的先后顺序是什么?
Oracle启动中,spfile.ora.init<SID>.ora.spfile<SID>.ora 这三个文件正确的先后顺序是什么? 解答:启动数据库,使用startup命令 ...
- Java多线程系列--“JUC线程池”03之 线程池原理(二)
概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
- Java多线程系列--“JUC线程池”04之 线程池原理(三)
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...
- Java多线程系列--“JUC线程池”05之 线程池原理(四)
概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...
- ThreadLocal系列(三)-TransmittableThreadLocal的使用及原理解析
ThreadLocal系列(三)-TransmittableThreadLocal的使用及原理解析 上一篇:ThreadLocal系列(二)-InheritableThreadLocal的使用及原理解 ...
- ThreadLocal系列(二)-InheritableThreadLocal的使用及原理解析
ThreadLocal系列之InheritableThreadLocal的使用及原理解析(源码基于java8) 上一篇:ThreadLocal系列(一)-ThreadLocal的使用及原理解析 下一篇 ...
- ThreadLocal系列(一)-ThreadLocal的使用及原理解析
ThreadLocal系列之ThreadLocal(源码基于java8) 项目中我们如果想要某个对象在程序运行中的任意位置获取到,就需要借助ThreadLocal来实现,这个对象称作线程的本地变量,下 ...
- 4xx错误的本质:服务器已经接收到请求
4xx错误的本质:服务器已经接收到请求, 路径错误! { URL: http://10.100.138.32:8046/3-0/app/account/maxin } { status code: 4 ...
- Eureka 系列(03)Spring Cloud 自动装配原理
Eureka 系列(03)Spring Cloud 自动装配原理 [TOC] 0. Spring Cloud 系列目录 - Eureka 篇 本文主要是分析 Spring Cloud 是如何整合 Eu ...
随机推荐
- 【Python自动化测试环境管理】tox
1. tox基本介绍 1.1 tox是什么? tox 是一个用于管理 Python 项目的自动化测试和环境管理工具.它的主要功能是创建虚拟环境并运行项目的测试套件,tox能够让我们在同一个Host上自 ...
- Audio DSP 链接脚本文件解析
上篇文章(智能手表音乐播放功耗的优化)讲了怎么优化音乐场景下的功耗,其中第二点是优化memory的布局.那么在哪里优化memory的布局呢?就是在本文要讲的链接脚本(ld)文件里.作为audio DS ...
- 【Linux】速查手册
查看Linux系统信息 arch #显示机器的处理器架构(1) uname -m #显示机器的处理器架构(2) uname -r #显示正在使用的内核版本 dmidecode -q #显示硬件系统部件 ...
- 【SpringCloud】SpringCloud Alibaba Sentinel实现熔断与限流
SpringCloud Alibaba Sentinel实现熔断与限流 限流与降级 限流 blockHandler 降级 fallback 降级需要运行时出现异常才会触发,而限流一旦触发,你连运行的机 ...
- 无需WebView,Vue也能开发跨平台桌面应用
前言 一直以来,使用Vue开发桌面应用大部分都是使用基于webview的方案,如electron,tauri等.不依赖webview的,移动端倒有不少,如Weex,NativeScript等,桌面端寥 ...
- C#/.NET/.NET Core优秀项目和框架2025年3月简报
前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的详细介绍.功能特点.使用方式以及部分功能 ...
- centos简单文件备份
1. 背景 现在有一个正在使用的服务器, 需要对服务器上的数据库数据.实验室文件以及采购平台文件进行备份, 将备份文件存储到另外一个服务器上, 要求留存最近七天的备份文件. 2.详细步骤 2.1 备份 ...
- java基础之线程池
一.线程池:提前创建多个线程存放到集合容器中,其中的线程可以反复使用,减少资源的开销 作用就是:线程执行完一个任务,并不被销毁,而是可以继续执行其他的任务 使用线程池中线程对象的步骤: 1. 创建线程 ...
- zk源码—7.ZAB协议和数据存储
大纲 1.两阶段提交Two-Phase Commit(2PC) 2.三阶段提交Three-Phase Commit(3PC) 3.ZAB协议算法 4.ZAB协议与Paxos算法 5.zk的数据存储原理 ...
- QT 的信号-槽机制
对于对象间的通信问题,很多框架采用回调函数类解决.QT 使用信号-槽解决对象间的通信问题,只要继承 QObject 类就可以使用信号-槽机制.信号-槽使用起来非常简单.灵活,发射和接收对象实现了解耦. ...