DML 语句与undo

 

  当我们发出一条DML,(比如 update t set col1='A' where col1='B') 语句时,

  其执行过程大概可以如下概括: 

 1: 在SGA 内存的share pool 里寻找相同的解析计划,找到就直接重用;如果没有,则生成新的执行计划。(所谓 解析计划简单理解就是针对SQL语句所引用的表进行表数据分布,表数据量以及列上的索引等相关信息的搜集)

 2: 假设根据执行计划,得出col1='B' 的记录存放在10号数据文件的54号数据块里。

 3: 服务器进程在buffer cache 里找一个可用undo数据块,如果没有发现,则到undo表空间里找一个可用的undo块,并调入buffer cache。(找不到就尝试获取其他undo segment里的 expired 状态的 extends; 如果仍然没有得到,undo表空间里的数据文件启用了自动扩展,则数据文件进行自动扩展;如果不能自动扩展,就尝试使用其它undo segment里的 InActive 状态的extends,如果以上步骤均无法获得可用空间,则报错啦,undo表空间不足!)  假设获得的undo数据块号为24,位于11号undo数据文件里。

4: 将改变前的值,也就是B放入11号undo数据块。

5: 由于undo数据块发生了变化,于是产生重做记录,假设重做记录号为120。

  行号  事务id    file#  block#  row  colum value

  120    T1      24       11        10    col1     B

6: 在buffer cache 时找到54号数据块。 如果没有发现,则从10号数据文件里调入。

7:将改变后的值,也就是A放入54号数据块。

8: 由于数据块发生变化,于是产生重做记录,假设重做记录号为121。

  行号  事务id    file#  block#  row  colum value

  121    T1      10       54        10    col1     A

9: 控制权返回给用户,如果在SQL*Plus里执行DML,则表现为光标返回。

10: 当用户发出commit命令时,触发LGWR进程,将120与121这两个重做记录写入联机日志文件,并将54号

数据块和11号数据块头部所记录的事务状态标记设置为已提交。然后控制权返回给用户,如果在SQL*Plus里执行DML,则表现为光标返回。

11: 这个时候,54号数据块以及11号undo块并不一定被DBWn写入数据文件。只有在脏数据块的数量达到一定程度才会被写入。

  

 

注意: 事务只要被提交或回滚,那么事务所使用的undo块数据就可以被覆盖。对于上面的例子来说,当第10步,用户发出commit命令后,11号undo块里的数据就可以被其它事务所覆盖。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值