日期:2014-05-16 浏览次数:20405 次
二者的由来,有二:
1)redo records的产生十分频繁
2)server process每次产生的量却不大
倘若每次产生的redo就须由大量高并发sp写入redo log file,则存在两个问题:
1)I/O开支大
2)redo file争用
由此,oracle在redo log机制中引入了log buffer和LGWR。
redo log buffer缓存了sp产生的redo records,提高了oracle高并发的性能。LGWR则将log buffer中的records批量flush到redo file。对于oracle而言,只要对数据库的改变写入到redo log file,那么相关的事务绝不丢失。
在事务提交时,会产生一个commit的change vector,这个CV被写入log buffer后,sp会发出一个信号,要求LGWR将和这个事务相关的redo records写入到redo file,只有这个事务相关的redo全部安全着陆,sp才会向client发出事务提交成功的信息“Commit Complited”。
由于redo entries实是娇贵且重要。为了保障redo records的安全,oracle还实现了:
1)LGWR绕过OS的缓冲直接写到redo log file,避免宕机而丢失redo
2)redo log file的block size和数据库的block size是完全不同的,事实上,和OS的I/O block size如出一辙,从而一个redo block在一次物理i/o时可以同时写入而不出现块断裂。
redo buffer是一个循环使用的顺序读写的buffer:
1)redo records写入log buffer是按顺序的
2)当log buffer写满后,会从头开始写(这种情况是不会出现的)
log buffer数据的写入是由sp完成的,这个写操作属于高并发,而log buffer的空间分配是个串行操作。所以需要锁的保护:
1)redo copy latch:写redo 到redo log buffer
2)redo allocation latch:控制log buffer空间分配
为了腾出更多的log buffer,oracle设计了LGWR写的触发条件:
1)commit时
2)1M redo entries时
3)超过_log_io_size参数指定的大小时
缺省值是LOG BUFFER大小的1/3,这个参数单位是REDO LOG BLOCK
SQL> col name for a15 SQL> col value for a10 SQL> SQL> select a.ksppinm name,b.ksppstvl value,a.ksppdesc description 2 from x$ksppi a,x$ksppcv b 3 where a.indx = b.indx 4 and a.ksppinm like '%log_io_size%' 5 / NAME VALUE DESCRIPTION --------------- ---------- -------------------------------------------- _log_io_size 0 automatically initiate log write if this many redo blocks in buffer
4) 每3秒
5)DWWn写之前写
LGWR写的具体过程:
1)先尝试获取redo writing latch,确保其他process不会继续触发lgwr(这里可能会产生log file sync等待事件)
2)获取redo allocation latch(public redo allocation latch),防止有新的change vector继续写入log buffer,造成LGWR无法确定应该写多少redo.
3)LGWR确定写的范