Oracle 事务流程有哪些

97次阅读
没有评论

共计 3679 个字符,预计需要花费 10 分钟才能阅读完成。

Oracle 事务流程有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

事务表:
事务表存放在 undo 段头部(undo 段头块),每一个 undo 段最多可以存放 47 个事务。
事务表按行存放事务记录,每行一个事务记录。
事务开始后,服务进程分配一个 XID,将事务信息(XID UBA)存放在 undo 的段头块。

Oracle 尽量一个事务使用一个回滚段,如果事务太多,会出现回滚段重用,多个事务使用同一个回滚段。并且 Oracle 会均匀的将事务分配在回滚段中。

查看当前事务信息

select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction ;XID XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL
06001C004B040000 6 28 1099 711 3
查看所有回滚段。SYS@prod Select * from v$rollname; 0 SYSTEM
 1 _SYSSMU1_3724004606$
 2 _SYSSMU2_2996391332$
 3 _SYSSMU3_1723003836$
 4 _SYSSMU4_1254879796$
 5 _SYSSMU5_898567397$
 6 _SYSSMU6_1263032392$
 7 _SYSSMU7_2070203016$
 8 _SYSSMU8_517538920$
 9 _SYSSMU9_1650507775$
10 _SYSSMU10_1197734989$
从事务信息中可以看出,当前事务使用的是 6 号 undo 段。找到 6 号 undo 段的段头块的位置:SYS@prod select header_file,header_block from dba_segments where segment_name = ‘_SYSSMU6_1263032392$’;
HEADER_FILE HEADER_BLOCK
 3 208
 3 号文件 208 块就为 undo 段的段头块。可以将其转储查看事务表:Alter system dump datafile 3 block 208
select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) block,id
from t1
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) BLOCK ID
 1 91041 5
 1 91041 5
 1 91041 5
查看行数据所在数据块的位置进而转储查看数据块结构。

事务槽 ITL:
事务槽存放在数据块的头部,事务修改一个数据块,需要在事务槽中记录事务信息。

XID 既是编号 又是地址。
1. 使用了哪个回滚段的段头块
2. 段头块使用了哪行来记录事务。
3. 第几次覆盖。(第几次循环使用)。

先简单叙述一下事务的流程:

1. 开始一个事务,首先 Oracle 给这个事务分配 XID,并找到一个回滚段,在回滚段头块将事务信息存放在事务表中,并给这个事务分配 undo 块,并将 undo 块的地址也写入事务表中(UBA 地址) 。2. 事务准备修改一个数据块,在该数据块的头部的事务槽中写入事务信息(XID ,UBA(这个 UBA 指向相对应的 undo 块))。3. 开始修改数据,将数据块修改的前映像存放在 undo 块中。

事务表中与事务槽中的 UBA 是不同的:
事务表中的 UBA:

事务表中的 UBA 是指向事务操作的最后一个 undo 块,同时也是事务回滚开始的位置。
rollback 回滚时,根据事务表中的 UBA 直接定位事务回滚的起点。
并且要知道回滚块与回滚块之间是串起来。

事务槽中的 UBA:
数据块中事务槽的 UBA 指向相对应的 undo 块,意义在于加快构造 CR 块的效率,
执行 select 时,服务进程如果发现该行数据正在有事务进行,且未提交,那么就会结合当前块以及 undo 块生成 CR 块(能够更加快速的找到相对应的 undo 块)。

事务槽中记录 XID 意义在于指向事务表,直接定位到事务表的位置,与 Oracle 提交方式有关,具体原因,后面描述。

一个 DML 事务开始时,需要修改的位置:
回滚段头部的事务表被修改
数据块块头部的事务槽被修改
undo 块被修改
数据块的行数据被修改
(以上四种修改都会产生 redo)

事务槽的数量查看:
Select ini_trans,max_trans from dba_tables where table_name =‘T1’

事务槽的争用问题:
会话 A 启动第一个事务修改该数据块中的一行数据,
需要在该数据块中获取一个事务槽(未提交)
(没有提交事务槽不能被覆盖,只有事务已经提交的事务槽才可以被覆盖)

会话 B 启动第二个事务修改该数据块中另一行数据
也需要在该数据块中获取一个事务槽
当事务槽获取上限以后
再来一个事务修改该数据块的其他行,就需要等待事务槽释放。

解决:
可以增加 pctfree 减少争用
Oracle 为了结局对事务槽的争用,对 insert 操作,Oracle 会将其分布到多个块中。
但是对 update 与 delete 无能为力,只能增加事务槽,所以 update 与 delete 容易出现事务槽争用。

事务槽中记录 XID 的意义:
Oracle 结合延迟块的清除实现快速提交:
如果一个事务修改了 1000 个块,事务信息在 1001 个块中存在(undo 段头部块)
当事务提交时,需要在 1001 个块的位置将事务记录修改为已提交的状态,会很慢。

并且还可能出现一种情况事务修改了 1000 个块,当要提交时,已经有 800 个块被写入磁盘。
Oracle 不可能再将这 800 个块重新读入磁盘,来将数据块头部事务槽中记录的事务修改为已提交状态。

Oracle 延迟块清除的办法:
当事务提交时,Oracle 仅更新 undo 段头的事务信息,根据 buffer 的数量,并且仅会更新部分 buffer,剩余 buffer Oracle 会在下次读取这些数据块时清除事务记录。

所以说 数据块中事务槽记录未必准确,如果数据块中事务槽记录的事务未提交,Oracle 还需要根据事务槽头部的 XID 去 undo 段头事务表来进一步判断事务是否提交,如果 undo 段头事务表记录该事务已经提交,那么 Oracle 会选择相信 undo 段头,进而修改数据块,并且将上一个事务的事务槽中的事务记录修改为已提交。

Oracle 的多种提交方式:
事务修改的数据块少时:
事务提交时
修改 undo 段头记录的事务状态
修改数据块头部事务槽中记录的事务状态
修改数据行标志(事务槽编号,指向事务槽,就是 Oracle 行级锁)

事务修改的块一般多时:
事务提交时
会将 undo 段头的事务表以及数据块头部的事务槽中的事务状态修改为已提交。
数据行标记(行锁)会在下次 select 访问时清锁。
(这也是有时 select 也会产生 redo 日志的原因)

事务修改的块很多时:
当事务提交时
仅会修改 undo 段头的记录。
事务槽,数据行标记(行锁)在下次 select 访问时修改清锁。

另一种情况:
如果一个数据块长时间未被读入到 buffer cache,而且数据块事务槽以及锁还未清除,如果此时读取,服务进程会去 undo 段头的事务表中判断事务是否已经提交,但是服务进程读取 undo 段头的事务表时发现,事务表已经被覆盖 15 次,此时 Oracle 会认定事务已经提交,因为事务未提交在事务表中不可能被覆盖,然后服务进程清除该数据块事务槽的记录,清除数据块行锁。

Select 流程总结:
(数据块中每行数据都会有指向事务槽的标记)
当客户端执行 select 查询时,服务进程接收请求,将符合要求的数据块读入到 buffer cache 中,服务进程会先去读取数据块中的行。
如果数据块的行上有事务槽标记(行锁), 服务进程会去事务槽中查看该事务槽中记录的事务是否已经提交。(由于快速提交,延迟块清除原则,锁信息并不代表事务情况)
如果事务槽中记录的事务已经提交,那么服务进程会清除数据块中这行记录的事务槽标记(行锁),直接读取该行数据。
如果事务槽中记录的事务没有提交,Oracle 会产生怀疑,服务进程会根据事务槽中的 XID 去 undo 段头部中的事务表中读取事务状态(事务槽中记录 XID 的意义)。
如果事务表中的事务状态为已提交,那么服务进程会认定这行数据所对应的事务已经提交,清空行标记,将事务槽中未提交状态修改为已提交。
如果事务表中的事务状态为未提交,那么 Oracle 会认定该数据块中行对应的事务未提交,此时服务进程就会根据当前块中的行数据来结合 undo 块来构造 CR 块,用于一致性读。

Update 流程总结:
简单的说,就是如果该行数据有事务正在进行,那么就需要等待
如果该行数据没有事务正在进行,那么就正常修改。
Oracle 两个事务可以同时修改一个数据块,只要行不冲突即可。行级锁的并发性

关于 Oracle 事务流程有哪些问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-03发表,共计3679字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)