相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx

上传人:b****6 文档编号:19300315 上传时间:2023-01-05 格式:DOCX 页数:19 大小:1.16MB
下载 相关 举报
相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx_第1页
第1页 / 共19页
相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx_第2页
第2页 / 共19页
相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx_第3页
第3页 / 共19页
相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx_第4页
第4页 / 共19页
相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx

《相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。

相克军 ORACLE 讲座 深度剖析UNDO段 笔记Word格式文档下载.docx

----------------------------------------

0SYSTEM

1_SYSSMU1$

.........

10_SYSSMU10$

--查询其中='

_SYSSMU1$'

这个段的占有多个块多少个区

SQL>

selectsegment_name,blocks,extentsfromdba_segmentswheresegment_name='

;

SEGMENT_NAMEBLOCKSEXTENTS

----------------------------------------------------------------------------------------------------

_SYSSMU1$193617

--查询'

这个段分配区的具体情

selectsegment_name,tablespace_name,extent_id,file_id,block_id,blocksfromdba_extentswheresegment_name='

SEGMENT_NAMETABLESPACE_NAMEEXTENT_IDFILE_IDBLOCK_IDBLOCKS

------------------------------------------------------------------------------------------------------------------------------------------------------

_SYSSMU1$UNDOTBS10298

_SYSSMU1$UNDOTBS11288498

.........................................

_SYSSMU1$UNDOTBS1162905128

由上面这个结果,可以得出结果:

UNDO表空间中的段中的区中的块儿是连续的,但是区与区之不是连续的

showparameterundo;

NAMETYPEVALUE

-----------------------------------------------------------------------------

undo_managementstringAUTO

undo_retentioninteger900

undo_tablespacestringUNDOTBS1

showparameterundo;

undo_retentioninteger900--ORACLE不希望已经提交的事务,对应的UNDO段中的区,立即就被覆盖,而设定这个参数undo_retention900表示事务已经提交之后,UNDO段中的区还可以在UNDO段中存活900秒,过期之后,才可以被覆盖

selectnamefromv$parameterwherenamelike'

%undo%'

undo_management

undo_tablespace

undo_retention

altertablespaceundotbs1retentionguarantee;

--表示undo_retention至少900秒以后,过期之后,才可以被覆盖

selecttablespace_name,retentionfromdba_tablespaces;

--查询设置结果

altertablespaceundotbs1retentionnoguarantee;

Undo段中区的状态

free空闲

expired过期:

超UNDO段中的区在提交之后,存活的时间超过了undo_retention900钞

inactive已经提交

active活动

ORACLE在自动使用Undo段中区时,先用“free”空间,实在不行,才用“expired”过期的空间。

如果空间还不够,用户“inactive”,如果还是空间不够,这时就要报错了。

进程就要挂起了。

ORACLE使用Undo段空间的顺序:

“free”空间--->

“expired”过期的空间---->

“inactive”空间---如果空间还不够---->

报错

检查UNDOSegment状态

SELECTusn,xacts,rssize/1024/1024/1024,hwmsize/1024/1024/1024,shrinks

fromv$rollstatorderbyrssize;

显示UNDO

selectextent_id,bytes,statusfromdba_undo_extentswheresegment_name='

selecta.usn,a.xacts,a.rssize/1024/1024/1024,a.hwmsize/1024/1024/1024,a.shrinksfromv$rollstataorderbyrssize;

2、图解一个事务的操作流程

Undo段的组成,段头、回滚块

事务ID

selecta.xid,a.xidusn,a.xidslot,a.xidsqn,a.ubablk,a.ubafilfromv$transactiona;

XIDXIDUSNXIDSLOTXIDSQNUBABLKUBAFIL

------------------------------------------------------------------

090016004B050000922135510332

事务表:

undo段的第一数据块,每一个回滚段最多可以47个事务

回滚段的段头块

selectheader_block,header_filefromdba_segmentswheresegment_name='

--将回滚段“_SYSSMU1$”这个段的段头块给dump文件:

altersystemdumpundoheader'

//转储回滚段头

selectspidfromv$processwhereaddrin(selectpaddrfromv$sessionwheresid=(selectsidfromv$mystatwhererownum=1));

--查看UNDO段段头块的内容dump出来的信息

cd$ORACLE_BASE/admin/$ORACLE_SID/dump/

viorcl_ora_9051.trc

altersystemdumpdatafile5block4038;

//转储回滚段数据块

事务槽:

一个事务修改一个数据块,一个数据块可能被多个事务修改。

在这个数据块的头部,有一个事务槽,可以写入1-255个事务。

开始一个事务,找到一个回滚段里找一到一个段,在它的控制槽里写上事务信息

在要修改的数据块的事务槽里写上事务信息。

此少要在两个位置写上事务信息:

1)回滚段的段头块里2)数据块的事务槽里。

UBA:

(undoblock)回滚块

要修改数据时,先将修改前的数据放到UNDO段里,叫回滚块

ORACLE事务处理的五大步骤:

第一件事:

一个事务开始,在UNDO表空间里找一个相对空闲的UNDO段,然后在这个UNDO段的段头块里边的事务表里,找到其中一个槽位,在事务表里的槽位里找一个行,

将自己的事务信息XID写上去。

同时在这个回滚段里给这个事务分配一个UNDO块,并且把这个UNDO块儿的地址写到事务表里去。

即在事务表里要写入两个地址:

xid(事务ID),uba(所分配的UNDO块儿的地址)

第二件事:

在修改数据块之前,首先找到这个要修改的数据块的头部,找到它的事务槽,在事务槽里找一行,把事务编号XID写上。

同时事务槽里与有个uba地址指向回滚块。

第三件事:

把要修改的五行信息写到UNDO块里(回滚块),并且把这个UNDO块儿的地址写到数据块里的事务槽里的uba地址。

第四件事:

接下来,还要修改其它信息,再分一个UNDO块,将新分配的uba地址记录到数据块的事务槽里。

第五件事:

事务表里的uba地址就指向了最新分配的UNDO块。

这样形成了两条链:

第一组链:

由数据块的事务槽的XID指向事务表的事务,同时,数据块的事务槽里的uba地址指向UNDO段里UNDO块的地址

作用:

利用这个链接,可以直接从数据块里找到回滚块,直接构造出CR块。

而不用通过事务表,找到回滚块。

疑问:

为什么事务ID,即XID同时存在两个地方:

事务表和数据块里?

为什么需要数据块儿的SID还要指向事务表里的事务ID。

第二组链:

事务表uba指向最新的回滚块,最新的回滚块能找到次新的回滚块,次新的回滚块能找到更新的回滚块,以此形成一条链。

事务表里的uba指向最新的回滚快。

使用最新的回滚块找到次新的回滚块,把次新的回滚块回滚了,这样依次往前回滚rollback。

总结:

一个事务开始以后ORACLE修改了1)事务段的段头块的事务表,2)UNDO块,3)数据块的事务槽,4)数据块本身

这四个被修改的地方都在数据块里。

所以全都会产生REDO。

所以REDO不仅仅记录数据的改变,而且记录了1)事务表的改变2)UNDO块的改变3)数据块事务槽的改变4)数据块的改变

5、读一致性

ORA-01555错误

6、undoadvisor

EM

7、事务槽ITL

默认是1

最大255(从ORACLE10G开始不能更改)

selectINI_TRANS,MAX_TRANSfromdba_tableswheretable_name='

T2'

事务槽的争用

事务槽的争用:

如上图,当未提交的事务不断增多,而多A事务和B事务都同时在修改这同一个数据块,而且都没有提交,没有提交的事务,事务槽信息是不可以被告覆盖的,必须保留,随着事务的增多,在这个数据块的事务槽里的事务信息会不断的增多,当又有新的事务需要写进这个数据块的事务增时,已经没有空间了,那就这个新的事务就需要等待别的事务提交,只有别的事务提交之后,这个新事务才可以写进去。

这就叫“事务槽的争用”。

如何防止事务槽争用:

1)对于往一个表中多个事务同时插入数据,INSERT操作时,ORACLE给每个事务开启一个数据块。

这样就不会产生事务槽争用。

2)但对于UPDATE和DELETE操作是没有办法解的,所以UPDATE和DELETE操作容易发生事务槽争用。

事务等待及行级锁的形成:

createtablet10(idnumber(5),namechar(2000));

insertintot10values(1,'

aa'

);

insertintot10values(2,'

bb'

insertintot10values(3,'

cc'

insertintot10values(4,'

dd'

insertintot10values(5,'

ee'

commit;

selectdbms_rowid.rowid_relative_fno(rowid)fno,dbms_rowid.rowid_block_number(rowid)block_number,id,namefromt10;

updatet10setname='

abcd'

whereid=1;

在DBA用户下:

selecta.ubafil,a.ubablk,a.xidusn,a.xidsqn,a.start_scnbfromv$transactiona;

selecta.ubafil,a.ubablk,a.xidusn,a.XIDSLOT,a.xidsqn,a.start_scnbfromv$transactiona;

将回滚段_syssmu2$的段头块dump成文本,放在$ORACLE_BASE/admin/$ORACLE_SID/dump/目录下,

_SYSSMU2$'

altersystemdumpdatafile2block3657;

查询DUMP出来的文件,查当前会话编号

selectspidfromv$processwhereaddrin(selectpaddrfromv$sessionwheresid=(selectsidfromv$mystatwhererownum;

SPID

------------

9614

cd$ORACLE_BASE/admin/$ORACLE_SID/dump/

事务槽dump文件的内容:

还可以指文件号和块号DUMP出来:

altersystemdumpdatafile4block421;

altersystemdumpdatafile4block422;

8、提交方式

事务的提交:

如果一个事务修改了1000个块,现在这个事务要提交,那么需要修改1001个块中的“是否已提交信息”,1000个数据块+1个事务表。

这时,有可能这1000个块儿已经有800写进了磁盘下了,那么需不需要把这800个块儿重新写到磁盘,再提交,如果这样,会不会很慢?

答:

ORACLE针对这个问题,采了快速提交的办法,即当ORACLE发些这次事务修改的数据块过多,提交时,只会更新UNDO表空间里的事务表的“是否提交”

信息给更新了,而数据块事务槽的“是否已经提交”不作更新,或者更新少量。

所以数据块事务槽的“是否已经提交”信息,不一定准确,但是事务表里的“是否已提交”信息一定是准确的。

疑问解答:

答:

如图所示,当另一个事务B需要对修改或查询同一个数据块的某一行时,而这一行已经被A事务修改,但是还没有提交。

些时ORACLE会走以下的程序流程:

从这里可以看出几个结论:

1)数据块的XID指向事务表是非常有用的。

2)ORACLE执行SELECT语句,也可能因为更改前面事务留在数据块事务槽里的“是否已提交”状态,而产了logbuffer,

进而生成redolog日志。

3)数据行上的ITL(事务槽的编号)指向事务槽,事务槽上有是琐已提交标识,这种机制实际上形成了ORACLE的行级锁。

4)对ORACLE最彻底的提交方式,是事务表里为“已提交”状态,数据块的事务槽为“已提交”状态,数据行的ITL被清除干净。

但实际上,数据行的ITL事务槽号没有清掉,留待下次查询时,再作清理,并且如果上一个事务较大时,数据块事务槽

里“是否已提交”标识不一定准确,但是事务表里的“是否已提交”信息一定是准确的。

ORACLE执行SELECT语句时,是很有可能产生REDOLOG日志的。

select读的过程分析如下:

ORACLE要读一个表,这个表有10000行,A事务8:

50开始读,8:

55时,另一个B事务删除了一行,并且提交了,9:

00时A事务读表有结果了,

请问ORACLE读到的是9999行,还是10000行?

读到的是10000行,ORACLE是如何实现的呢?

ORACLE在时间8:

50时读这个表的时候,把时间点记下来,生成一个SCN(850),此时此刻,所有的

数据块的事务槽里的SCN都是<

=850的。

1)在事务中,对四个地方的修改(数据行、事务槽、事务表、回滚块)全部产生的REDOLOG

2)对数据块的所有修改全部产生RODOLOG

一个数据块可以依据UNDO块数据一直往历史方向找出任意时间的数据块。

如图所示,

只要UNDO表空间足够大,那么可以利用回滚块和当前数据块,不断的构造出CR数据块,以些不断往历史方向构造。

ORACLE的ORA-01555错误

4、图解Oracleprivateredostrands机制

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

select*fromv$transactiont,v$rollstatr,

v$rollnameu,v$sessions

wheres.taddr=t.addrandt.xidusn=r.usnandr.usn=u.usn

orderbys.username;

检查UNDOSegment状态

selectusn,xacts,rssize/1024/1024/1024,

hwmsize/1024/1024/1024,shrinks

fromv$rollstatorderbyrssize;

确定当前例程正在使用的UNDO表空间:

showparameterundo_tablespace;

select*fromv$parameterwherenamelike'

显示数据库的所有UNDO表空间

select*fromdba_tablespaceswherecontents='

UNDO'

显示UNDO表空间统计信息

selectto_char(begin_time,'

HH24:

MI:

SS'

)BIGIN_TIME,

TO_CHAR(end_time,'

)END_TIME,undoblks

fromv$undostatA;

显示UNDO段统计信息

selecta.name,b.XACTS,b.WRITES,b.EXTENTSfromv$rollnamea,v$rollstatb

wherea.usn=b.usn;

显示活动事务信息

selecta.username,b.name,used_ublk

fromv$sessiona,v$rollnameb,v$transactionc

wherea.saddr=c.SES_ADDRandb.usn=c.XIDUSN

anda.username='

HR'

UNDO表空间大小确定

selecttotalundo/((end-begin)*1440*60)undo_zize_per_secfrom

(selectmax(end_time)end,min(begin_time)begin,sum(undoblks)*8192totalundo

fromv$undostat

select140.741516648953*60/1024fromdual;

UNDO与REDO的关系:

他们没有什么关联

执行下面SQL语句,ORACLE的处理全过程:

updatet1setc1='

A'

WHEREC1='

B'

1)找到包含C1='

的数据据,假设是【4,120】

2)找到一个可用的UNDOBLOCK,假设是【2,300】

3)产生一个redo,去描述(保护)针对UNDOBLOCK的写入操作。

redo_addrSCNfile#block#operation

1009:

003400insert'

4)把'

放入UNDOBLOCK.

5)产生一个REDO,去描述(保护)针对UNDOBLOCK的写入操作。

003400'

-->

'

A’

6)把‘A’写入[4,120].

以后一担rollback,oracle可以直接把UNDO里的数据重新覆盖过来

ORACLE不提供脏读:

(我的修改,当我没有提交时,别人是读不到的)

比如:

A用户在9:

00执行一个查询SQL,这个表有10000条记录,这个SQL需要执行10分钟才能完成,

但是在9:

09时,B用户把这个表

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 信息与通信

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1