oracle提交事务时如何使用回滚和重做日志
1。 在sga区中产生回滚段的记录(rollback segment)。
2。 在sga的数据库共享池中修改了数据。
3。 已经在sga的重做日志缓冲区中为以上两条的缓冲做了重做记录。
4。 取决于上面3项的大小和消耗的时间,一部分上面的记录转移到磁盘上。
5。 已经获得所有的锁。
当commit的时候,所有剩下的工作就是:
6。为事务产生一个系统改变号(system change number) SCN
7。LGWR把所有余下的缓冲池中的重做日志条目写到磁盘上,并且在联机重做日志中记录SCN。实际上,这个步骤就是commit。如果发现这个步骤,就已经是提交了,删除了是事务条目,就表示已经提交了。在v$transaction视图中的记录将消失。
8。释放所有会话占用的所有锁,释放在入队列等待中被占用锁定的每个事项。
9。访问多个修改事务块,如果它们仍在缓冲区告诉缓存中,用快速模式访问和“清除”。
插入一条关于第九步的内容解释
(块清除是为了满足快速的commit操作而引入的,他使得Oracle在进行数据提交时尽量快的完成,使事务提交平滑.
当事务提交时,正常情况下应该清除影响的数据块上的ITL事务链表,更新row directory,反映出delete操作的行标识,但是如果事务较大,影响的数据块非常多,超过了缓冲区的10%,此时commit不会清除数据块上面的相关信息,而是保留到下次对这些数据块的访问的时候,这样导致下次访问数据块的速度比正常情况下慢很多(特别是大型的批处理),他要清除上面的ITL链表,row directory,SCN号等,此时还会产生redo信息(select也会))
整个commit过程中,最费时间的只是LGWR写重做条目到磁盘上,这个要涉及到物理硬盘的I/O。
LGWR是连续刷新的,
1。 每3秒
2。 当满1/3或1M时
3。 碰到任何事务的commit提交。
在事务rollback的时候,因为在rollback之前已经执行了以下操作
1。 在sga区中产生回滚段的记录(rollback segment)。
2。 在sga的数据库共享池中修改了数据。
3。 已经在sga的重做日志缓冲区中为以上两条的缓冲做了重做记录。
4。 取决于上面3项的大小和消耗的时间,一部分上面的记录转移到磁盘上。
5。 已经获得所有的锁。
当rollback发出的时候,
6。 撤销所有已做的修改。通过rollback记录来完成。insert的操作就delete。update,逆向修改。delete的操作就再insert。
7。 释放所有会话中被占用的锁,释放所有在队列中等待被占用锁定的每个事项。
对比下来,rollback比commit做的要多一些。