oracle学习笔记读一致性(ora-01555错误机制分析)及undo表空间大小设置

新站 新站     2023-03-01     272

关键词:

Oracle 学习笔记 读一致性(ORA-01555错误机制分析)及Undo表空间大小设置

这节课我们把和undo相关的另外一个技术、另外一个细节读一致性再深入地讲一下

一)一致性读和事务

一个事务开始以后

分配undo段头事务表和undo块
事务表指向undo块

数据块中有事务槽,底下有数据行
数据块事务槽中事务id指向事务表

事务表指向undo块
数据块事务槽也指向undo块

修改数据块中的数据行
修改的时候有指向关系
数据行指向数据行对应事务槽

A事务修改数据行以后
这个数据行指向数据块的A事务的事务槽

事务槽中有事务信息也有回滚块信息
回滚块信息指向undo块
事务信息指向undo段头的事务表

B会话访问同一数据行
发现这个数据行有锁定标记
就是数据行有一个数据指向事务槽

在行发现有链指向事务槽说明这个事务没有提交
这时不能读
B就构造一个cr块

这个cr块里面
没有修改的数据行写上

修改的数据行
根据锁定标记找事务槽
根据事务槽uba信息找undo块
undo块中把这一行找出来
把修改前的数据找出来写到cr块中
构造出来一个cr块
然后B读这个cr块

cr块中有一行是从undo块中读的
是事务提交前的信息,也就是说是事务修改前的信息
通过刚才我讲的技术oracle避免了脏读

一个会话读到了另外一个会话未提交的事务所修改的数据叫脏读

oracle保证你读的数据永远是提交后的数据,未提交的数据你不会读到

读一致性里面最简单的oracle通过回滚数据避免了脏读

二)一致性读的事务实现

1)一个例子

再来往深里研究一下

我们有这么一个需求
oracle读一个表这个表很大比如说一万行
当然实际中10000行很小了
假设十万行一百万行,咱们就说一万行
oracle要读一个表10000行
假设这个过程的时间拉长了

8:50开始读这个表,这个表有一万行
8:55的时候这个表的最后一行被删了被提交了
9:00的时候oracle读完这个表了

按照刚才那个分析应该是读9999行
因为读到最后一个块的时候块里面的所有的行的所对应的事务已经提交
它应该会直接读出来9999行
其实oracle会读出一万行来
这也是读一致性的要求

我们可以这么认为
oracle要读一个表的时候
首先对这个表做一个快照
快照就像照一个像
接着从头读到尾
读的是静止的状态

oracle 8:50读这个表的时候
啪给这个表照一个像
照的是8:50的时刻然后接着就开始读
从头到尾读表的所有的行都是8:50那一时刻的这个数据
这个时候应该是对的
也就是我们读的是1万行

oracle希望是这样

给大家分析一下oracle如何来实现的

这里面有几个关键技术

2)scn时间点

oracle在8:50开始读这个表的时候
也就是开始执行这个select语句的时候
oracle把时间点记下来
就是SCN850,假设scn是这样的,我们用一个字符串来表示更好一些
8:50的时候执行了select这时候它把这个时间点记下来scn850

假如我8:50的时候突然时间静止了
这个时候我敢保证目前所有的数据块,或者说目前我要读的所有的数据块
它里面的事务槽的scn都小于8:50

也就是好像
我这个屋子
现在8:50我突然让时间静止8:50
这个屋子里面所有的东西都是8:50以前生产的
不可能现在8:50了
这个屋子你找出一个东西来它是9:00生产的
那不现实

现在是记住了scn8:50或scn850

现在保证
oracle接下来读的在8:50这个时间点

oracle要读的这个表的所有的数据块的事务槽里的scn都小于850或小于等于850

有了这个做基础了
select语句执行的时候先把时间点记下来

3)事务产生redo和undo

我们先来分析这个事务

一个事务开始了,
开始的时候事务表加上一行信息

假设有两个回滚块,回滚块之间有链接指向

事务表中的这行指向该事务的最新回滚块

这个事务有可能修改很多数据块

数据块中有事务槽
事务槽指向事务表
数据块事务槽中的uba地址指向回滚块

在这个事务的整个的执行过程中

先是事务表
再就是回滚块、事务槽、数据行

数据行修改了指向数据块对应的事务槽

从数据行到事务槽
从事务槽到回滚块
从事务槽再到事务表
事务表再一步步到回滚块
这整个的形成一个链状

在这个过程中有几个关键点

第一、
在这个事务所修改的所有的地方都产生redo
修改了事务表、回滚块、事务槽、数据行
修改的这四个地方全部产生redo

第二、
对数据块的所有的修改全部产生undo
包括事务槽
也就是当我要覆盖一个事务槽的时候
我一定会做一件事情
把原来事务槽的信息也放到undo块里面去

第一都产生redo
第二对数据块的所有的修改全部产生undo

第二个数据块同样

4)事务槽的覆盖

引申一下假设现在对这个数据块来讲

8:50的时候我们找到这个数据块
这个时候这个数据块的里面的scn是scn840
因为这个数据块在8:40的时候做过修改同时提交了

在8:50这个时刻这个数据块事务槽是scn840

数据块被修改首先来讲会产生事务表、回滚块
因为一个新的事务重新分配事务表重新分配回滚块,和原来的没关系

修改的时候
因为上个事务槽被修改了已经提交了
可以覆盖了
数据行因为提交了也可以被修改

这时候第二个事务8:55的时候要修改这个数据块
先把事务表以及回滚块给准备好了
接着要修改数据块
要修改的数据块除了redo都产生以外
这个数据块修改的包括事务槽以及包括这个数据行都要被undo
这时候这个事务槽信息和数据行信息都被写到回滚块里面去
这里面各个事务信息的链就会发生变化

数据块的事务槽数据
新事务槽产生覆盖了原来的事务槽
被覆盖的事务槽被写到undo块

undo块中的老事务槽也有指向

仍有指向undo段头事务表

原来事务槽位置中新的事务槽原来对undo块的指向去掉了
老的事务槽现在在undo块中的事务槽
仍是原来的指向,指向它原来的undo块

因为原来的数据块的这些信息这个事务槽信息和数据行信息
都被移走了移到undo块里面去
自然地址也被移走了
出现了在undo块中备份的事务槽的这种指向的情况

数据块产生新的事务槽
自然指向新的事务
这个事务指向最新的undo块
但这时undo块中有原来的事务槽的备份

这时候新的事务槽scn是855了,scn855
这个新的数据块中的事务槽还指向最新的这个事务的undo块回滚块

5)事务cr读结果

8:50开始的查询
当9点钟的时候要读这个数据块

读的时候发现这个块的事务槽的scn是855
显然大于850
它就确认这个块在8:50以后做过修改
既然做过了修改
我要找8:50以前的数据就要构造cr块

cr块显然是数据块里面的数据行加上undo数据

根据事务槽找到事务再找到undo块
把事务槽和数据行拿回来

在cr块里写入事务槽、数据行,构成一个cr块

undo块拿出来的事务槽
这个事务槽里面的scn是840
构造出的cr块里面的事务槽里面的scn是840
840显然小于850
小于850的话cr块可用
这一行数据读出来了

这就是读出一万行的一个原理所在

三)事务的递归回滚

对一个数据块来讲
根据事务槽找到这个事务
根据这个事务我再找回滚信息
在回滚信息里面还可以找到更老的一个事务槽
更老的事务槽又对应着相应的事务
事务又找回滚
又可以找到回滚数据
在回滚数据里面又对应着一个更更老的一个事务槽

再往前走,还可以一直再往前走

通过这个我们可以看到一个知识点

可以这么认为
一个当前的数据块
根据回滚信息可以一直往前找
在undo数据保留时间足够长的情况下
可以找到对这个数据块所做的所有的修改过的一些回滚数据

这个数据块现在是9:00
我可以找到8:55的这个数据块的状态
如果undo数据有的话
可以找到8:40的、8:30的、8:20的、昨天的、前天的、大前天的
甚至上个月的

如果undo表空间里的数据足够多的话
我从当前的数据块以当前的数据块为起点
沿着undo数据一直找、找、找的话
可以找到最早的对这个数据块修改的所用的事务以及回滚数据
也就是说这个数据块此前的所有的undo数据是以链状的形式串起来的

原理就是因为一个数据块
我记录undo数据的时候
不仅仅记录修改的数据行,事务槽也被记录了

到目前为止记住一句话就可以了
一个数据块,根据这个数据块的undo数据
一直往前找,一直往前找,可以找到足够早的这个数据块的一个回滚数据

比如说先前的数据块是9:00
我可以通过当前块找到数据块9:00的状态
还可以根据undo数据找到8:50的
再往前找到8:40的,再往前找8:30的、8:20的、8点10分、8点5分甚至7点
可以一直往前找
因为undo数据时串在一起的
当然前提是undo数据足够长足够大,undo表空间足够大

四)ORA-01555错误

再看一个例子

8:50的时候开始读这个表读这个数据块
记下这个时间点

在8:51的时候,这个表的最后一行被删了被提交了

8:52的时候这个数据块又被删了一行然后又被提交了

8:53的时候这个数据块又被删了一行又被提交了

8:55的时候我读这个数据块的时候
我发现这个数据块里面事务槽的scn号是8:53

8:53显然大于8:50,我需要往前构造cr块
第一步把8:53的回滚了构造出8:52的

8:52不满足,我再构造构造8:51的

还不满足,再构造,构造8:40的

ok!小于8:50了
这时候这个cr块构造出来了可以读了

有可能出现这种情况

事务在8:50开始在8:55读到这个块的时候

往前构造
构造出8:53的没问题,因为这个事务刚发生的

8:52也构造出来了
但是8:52构造出来后再往前构造的时候没有了

因为8:51这个事务提交的时间比较早了
它的undo数据有可能被覆盖,8:51的数据没有了

也就是我要读这个数据块的时候
我构造cr块最早能够构造到8:52

这个时候oracle就会报错
报一个:snapshot too old
就是很经典的ORA-01555错误
就是需要构造出来的快照的时间点太老了,已经没法构造出来了

原因是:
第一、这个sql语句,这个select执行时间太长
第二、undo表空间压力很大,导致你的undo数据被覆盖

第一、如果你的select语句时间很短两秒钟就执行完了
可能就没有我刚才的问题
第二、如果你的undo表空间压力不大
这个时候它优先会使用free和expired这些区
你的8:51的数据可能会一直存在,可能7点的6点的数据都存在
不会出现snapshot too old

所以说oracle的01555错误产生原因有两个
第一个sql语句的执行时间过长
第二个undo表空间的空间压力很大,undo表空间的undo数据保存时间过短

对第一个问题我们往往没办法解决
因为你的执行时间不好控制,确实执行一个长select语句
但是我们可以增加undo表空间来缓解这个错误

这就是snapshot too old机制
就是01555错误原因

五)设置undo表空间大小

undo表空间大小怎么来设置
通过EM来看一下

进入EM
在EM主页的相关链接有一个 指导中心 链接

进入指导中心页
在 指导 部分有 还原管理 链接

进入 还原管理 页

建议案 部分 有以下的一个部分

系统活动和表空间使用情况
此建议案基于所选分析时段的系统活动和还原表空间使用情况。
运行时间最长的查询 (秒) 0.0
平均还原生成速率 (KB/分钟) 56.0
最大还原生成速率 (KB/分钟) 548.0

列出了
运行时间最长的查询
还有undo的生成速度每分钟是多少的统计信息

01555错误
第一个和undo表空间的空间压力就是undo数据生成速度有关
再就是指令运行时间有关

知道这两个参数以后
oracle就可以确定你undo段该设多大了

接着点击
还原管理 页 中的 还原指导 按钮
进入 还原指导 页

有一个图 说明 还原保留时间所需的表空间大小

横坐标:还原保留时间(分钟)

代表着要undo数据保留多长时间

纵坐标:所需表空间大小(MB)

是在系统当前负载的情况下
你要保留undo数据一定长的时间就需要对应大的空间

有了横坐标以后纵坐标自然就有了

横坐标表示你要保留多长时间
我们要保留的时间至少应该大于最长的sql语句执行的时间

比如最长的sql语句执行时间是10分钟
这时候我就找到10分钟横坐标这个点
对应着找undo空间需要多大

但在实际的工作中
undo保留的时间
除了我们要考虑最长的sql语句以外
还要考虑比如说将来的闪回
我有可能今天突然想把昨天的数据闪回来
就是闪回到昨天
这个时候需要保留的时间更长一些

也就是说
你首先要确定数据库这个undo保留时间到底希望是多少
这个考虑因素不仅仅是最长sql语句了还有一些别的内容
确定好时间以后
自动对照图表找这个undo空间大小就ok了

举例讲有时候我们希望保留24小时或保留一个月的undo数据
都是有可能的

图的横坐标单位是分钟
把时间化为分钟以后
从图中对应着找大小就ok了

这就是我们这个图表的使用

关于undo的一些信息后面还会陆陆续续提到
总之undo该设多大
就是根据时间找大小
这个时间到底是多少,根据业务需求去定
至少应该大于最长sql语句的执行时间

这是EM中关于undo表空间大小的设置

六)和undo相关的sql语句

查看回滚段的使用情况,哪个用户正在使用回滚段的资源

select s.username, u.name from v$transaction t,v$rollstat r,
v$rollname u,v$session s where s.taddr=t.addr and
t.xidusn=r.usn and r.usn=u.usn order by s.username;

通过这个可以知道各个回滚段的负载情况

检查UNDO Segment状态

select usn,xacts,rssize/1024/1024/1024,hwmsize/1024/1024/1024,shrinks
from v$rollstat order by rssize;

xacts是事务数量等等一些信息

还有一些内容在以后讲优化的课程的时候再给补上
这个地方只是讲了oracle的undo的一些原理知识以及undo的设置

2017年8月28日
文字:韵筝

oracle数据库ora

...改了,进入回滚段试图找到那个块的撤销信息,从而得到一致读。这时发现需要的信息已经不存在,ORA-01555出现,查询失败。(3)发生的情况是:下一个session在块修改后第一次访问它时,需要检查最后修改块的事务是否仍被激活,... 查看详情

oracle数据库ora

...改了,进入回滚段试图找到那个块的撤销信息,从而得到一致读。这时发现需要的信息已经不存在,ORA-01555出现,查询失败。(3)发生的情况是:下一个session在块修改后第一次访问它时,需要检查最后修改块的事务是否仍被激活,... 查看详情

用expdp导出报错求教ora-39126,ora-01555

...PW$WORKER.FETCH_XML_OBJECTS[TABLE:"ZJY"."T_NAME_1"]ORA-01555:snapshottooo 查看详情

ora-01555异常处理

突然断电产生LOB大字段的损坏报错通常是ORA-01555:snapshottooold:rollbacksegmentnumberwithname""toosmall或者ORA–00600未知错误等,如果按快照太旧这个根本解决不了问题,因为查询会发现UNDO表空间使用率很低,其实是该表有BLOB或CLOB字段损坏... 查看详情

oracle频繁的提交会不会容易导致ora-01555错误

不会,频繁提交会释放相关资源比如说回滚段。操作不提交才会持续持有会滚蛋,导致ora-01555参考技术A不会,但是过度频繁提交对系统性能有影响。 查看详情

ora-01555错误

有这样一种情况0:00我们开始查询,查询的数据是100万条0:01一个sessionupdate了第100万条数据0:01update提交了,完成1:00我们的查询还在继续,只读到了20万1:01还有很多的事务在运行3:00我们的查询还在继续,读到了60万4:00事务量较大,... 查看详情

数据泵导出报ora-01555ora-22924

今天对某数据库执行数据泵导出操作时碰到如下错误:ProcessingobjecttypeDATABASE_EXPORT/SCHEMA/JOBProcessingobjecttypeDATABASE_EXPORT/SCHEMA/TABLE/POST_INSTANCE/PROCACT_INSTANCEProcessingobjecttypeDATABASE_EXPORT/SCHEMA/TABLE/PO 查看详情

ORA-01555: 快照太旧: 名为 "" 的回滚段号太小

】ORA-01555:快照太旧:名为""的回滚段号太小【英文标题】:ORA-01555:snapshottooold:rollbacksegmentnumberwithname""toosmall【发布时间】:2011-06-2006:59:57【问题描述】:ORA-01555:快照太旧:名称为“”的回滚段号太小当我调用过... 查看详情

翻译自mos文章使用aum(automaticundomanagement)时遇到ora-01555错误---原因和解决方式。

使用aum(AutomaticUndoManagement)时遇到ORA-01555错误---原因和解决方式。參考原文:ORA-01555UsingAutomaticUndoManagement-CausesandSolutions(DocID269814.1)适用于:OracleDatabase-EnterpriseEdition-Version9.0.1.0andlaterInformatio 查看详情

oracle数据库ora-01555快照过旧是怎么回事?怎么解决?

与你分享ORA-01555错误的几种解决方案,一般来说可以采用下面的方法:适当地设置参数UNDO_RETENTION(要大于执行运行时间最长的事务所需的时间)。可以用V$UNDOSTAT来确定长时间运行的查询的持续时间。另外,要确保磁盘上已经预... 查看详情

快照太旧错误

...我运行工作流超过5小时时,我经常收到“”。我的源是oracle,目标是Teradata。请帮助解决这个问题。在此先感谢【问题讨论】:dba-oracle.com/t_ora_01555_snapshot_old.htm【参考方案1】:我读过的关于ORA-01555snapshottooold错误的最佳解释见 查看详情

oracle学习笔记事务概述

...#xff0c;一个是commit一个是rollbackoracle中最重要的就是数据的一致性、数据的安全以及oracle数据的优化这几块是非常重要的事务它关系到数据的一致性对oracle数据库来讲或者对任何数据库来讲数据的一致性是重中之重作为DBA去维护ora... 查看详情

mysol学习笔记之事务处理

1事务隔离性实现原理   数据库事务会导致脏读、不可重复读和幻影读等问题。  脏读:事务还没提交,他的修改已经被其他事务看到。  不可重复读:同一事务中两个相同SQL读取的内容可能不同。两次读取之间其他... 查看详情

oracle学习笔记事务acid及隔离级别

...事务的含义事务的含义有一个说法叫ACIDA就是原子性C就是一致性I是隔离性D是持久性叫ACID下面内容摘自老师的讲义事务的含义1、原子性(Atomicity)事务的原子性是指事务中包含的所有操作要么都做,要么都不做,保证数据... 查看详情

java多线程之juc包:reentrantreadwritelock源码学习笔记

...的访问有两种方式:读和写,读操作一般不会影响数据的一致性问题。但如果我们使用ReentrantLock,则在需要在读操作的时候也独占锁,这会导致并 查看详情

easyexcel学习笔记-读excel(代码片段)

EasyExcel学习笔记-读Excelpom.xml添加依赖测试数据实体类自定义转换器最简单的读写法1写法2写法3写法4多行头(跳过N行)读多个sheet读全部sheet读部分sheet同步的返回读取表头数据额外信息(批注、超链接、合并单元格信... 查看详情

easyexcel学习笔记-读excel(代码片段)

EasyExcel学习笔记-读Excelpom.xml添加依赖测试数据实体类自定义转换器最简单的读写法1写法2写法3写法4多行头(跳过N行)读多个sheet读全部sheet读部分sheet同步的返回读取表头数据额外信息(批注、超链接、合并单元格信... 查看详情

zookeeper学习笔记一一致性协议

本文学习内容来自:《从Paxos到ZooKeeper分布式一致性原理与实践》电子工业出版社分布式架构分布式的特点:对等性并发性缺乏全局时钟分布式环境的问题通信异常网络分区三态节点故障从ACID到CAP/BASEACID原子性(Atomicity)一致性... 查看详情