log buffer内部管理:
1. 生成redo record (重做记录)
2. 重做记录写入online redo log
session1 :
update tab1 set col='cdf' where id=1 ;
Oracle先找出id=1的block(假设file#=4,blk#=120)放入 data buffer cache中,然后找出一个可用的回滚段数据块
(假设file#=2,blk#=19), 将这个回滚段数据块读入data buffer cache, 将col字段变化前的数据'abc'放入data buffer
cache 中该回滚段块中,同时生成重做记录, 然后用字段col的新值'cdf'更新data buffer cache中id=1的block
(file#=4,blk#=120), 再生成重做记录 (注意: 这时数据是否写磁盘还需要看是否触发lgwr及dbwr条件,这里暂不讨论) 。
这时候如果又有session2 : update tab2 set c1=10 where c1=9 ;
然后session1 又发出 update tab set col='xyz' where id=2 ; 然后commit;
那么我们生成日志缓冲区是(下面每行代表一个重做记录):
行号 事务id file# blk# row column value
1 T1 2 19 - - abc -- session1 回滚段中保存旧值
2 T1 4 120 1 2 cdf -- session1 更新新值到表的数据块
3 T20 2 30 - - 9 -- session2 回滚段中保存旧值
4 T20 5 200 20 1 10 -- session2 更新新值到表的数据块
5 T1 2 19 - - abc -- session1 回滚段中保存旧值
6 T1 4 120 2 2 xyz -- session1 更新新值到表的数据块
7 T1 commit SCN timestamp -- session1 提交
最后commit产生最后一个重做记录,这个重做记录只有一个改动向量,用来记录对回滚段事务表(在回滚段段头)的
更改(更新事务表中该事务的状态) 。 用户发出commit后,系统会触发LGWR进程,这时LGWR会将上面所有重做记录
(每行)写入联机日志文件中,包括尚未提交的事务T20 . 每次提交,log buffer中都会有一个SCN号生成。
一旦写入online redo log, 这部分的buffer就可以释放了,可以被新生成的重做记录覆盖。
之所以设置为达到3秒或达到1/3大小或1M 就触发LGWR, 是为了在LGWR进程将log buffer中的重做记录写入联机
日志文件时,log buffer中还是有剩余的可用空间以供其他进程所使用 (不管如何计算基本都会有剩余可用空间) 。
log buffer 组提交 :
下面有多个session发出的更新语句,在第一个commit发出时,会触发LGWR写联机日志文件,但是如果正在写
联机日志文件的过程中(还没有完成),有其他事务也发出提交语句(比如下面的T9/T18事务发出的commit), 那么
这时LGWR进程不能立即将这些事务(8~15行)的重做记录写入硬盘,而必须等待当前的写操作(1~7的重做记录写入
联机日志文件)完成。当第一个事务的重做记录(1~7)都被写入到硬盘中后,LGWR进程将重做日志缓存中的数据
一次性全部写入重做日志文件。
备注:
“lgwr当时正在将重做记录写入联机日志文件(还没有完成)” 是”组提交“的前提。
It's needed for the multiple commits (that follow the current one) to be group committed.
行号 事务id file# blk# row column value
8 T20 2 39 - - 289
9 T20 5 498 220 3 190
10 T9 2 90 - - hhh
11 T9 9 100 20 9 xxx
12 T9 commit SCN timestamp
13 T18 2 189 - - 18
14 T18 10 29 300 10 20
15 T18 commit SCN timestamp
--------------------------------------
摘录自www.itpub.net
http://www.itpub.net/thread-1311084-1-1.html
--------------------------------------
When LGWR is busy writing to the log file, Oracle allows server processes to issue commits
and those processes write commit markers into log buffer. It's obvious multiple processes
can write multiple commit markers, as in this case. After LGWR finishes writing whatever it
was writing, it comes back to the log buffer and finds a bunch of new log entries (including
2 commit markers). It just writes all these new entries to the log file. "第一个commit 就应该
触发LGWR" is correct only if LGWR is not writing at the moment.
Speaking of this, here's some more thought. Even though a regular session (server process)
is allowed to write a commit marker into log buffer without being blocked, the session
actually should be blocked as the user sees it, waiting on 'log file sync' wait, which ends
when LGWR finishes writing this session's log entries and the commit marker into the log file.
Yong Huang
--------------------------------------
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-664533/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/35489/viewspace-664533/
本文详细解析了Oracle数据库中事务处理过程,包括生成重做记录、更新表数据、处理并发提交和组提交等关键步骤,并阐述了日志缓冲区的作用及其在事务处理中的动态管理。
1069

被折叠的 条评论
为什么被折叠?



