|
[[B]小结
从以上分析可以看出update事务的大致流程:
1. 分配一个回滚段,获得usn
2. 在回滚段事务表中分配一个事务槽,获得slot,seq和uba(先写Redo logbuffer)
3. 更新datablock上的ITL(xid,uba)
4. 把旧值记录在undo block内(先写Redo Logbuffer)
5. 更改datablock的内容(先写Redo Logbuffer)
提交(commit)
1. 在回滚段事务表中标记该事务状态为commited(先写redo logbuffer)
2. LGWR 把Log Buffer写入Redo Logfile
3. 告诉用户事务已提交
4. 如果此时data block仍然在Buffer Cache中且没有被写回到磁盘或要清除的data block没有超过db cache的10%,那么commit SCN将被记录到Block Header上(fast block cleanout),否则下一个访问这个data block的进程将会从回滚段中获取该事务的状态,确认该事务被提交,然后这个进程获得commit SCN并写回到Block Header上(delayed block cleanout)。
[/B]
针对文中的分析及总结,补充一下个人的看法:
1:没有考虑到锁的影响.如果出现分配回滚段前有锁,则做怎样的处理?猜测:此时在for update的事务中是不会有旧值之说的;而是将新值写到 redo buffer 的对应栏位.
2:没有将测试环境说出来,因为在不同环境下事物流程有细微差别,如使用flash recovery;
3:另文中的10%这个数据是怎样得到的?
个人认为如果此文能够将出现的异常考虑在内并由此分析则对backup/recovery的原理会有帮助!
其实Oracle针对DML or DDL语句总是"先日志后修改"---先记录变化的情况然后再进行数据的修改.这是从SCN上可以看出. |
|