三.日志切换和REDO LOG 文件
当前台进程在LOG BUFFER 中分配空间的时候,实际上已经在REDO LOG 文件中预先分配了空间,如果REDO LOG 文件已经写满,无法再分配空间给前台进程的时候,就需要做一次日志切换,这个时候前台进程会想LGWR 发出一个日志切换的请求,然后等待log file switch completion 等待事件。
日志切换请求发出后,CKPT 进程会进行一次日志切换CHECKPOINT,而LGWR 开始进行日志切换工作。首先LGWR 进程会通过控制文件中的双向链表,查找到一个可用的REDO LOG 文件,作为新的CURRENT REDO LOG。 查找新的CURRENT REDO LOG 的算法是要求该日志是非ACTIVE 的,并且已经完成了归档(如果是归档模式),Oracle 会优先使用unused 状态的REDO LOG 组作为CURRENT REDO LOG。
在做日志切换时,首先要将LOG BUFFER 中还没有写入REDO LOG 文件的REDO RECORD 写入当前的REDO LOG 文件,然后将最后一个REDO RECORD 的SCN 作为本日志文件的HIGHSCN 记录在REDO LOG 文件头中。这些操作完成后,就可以关闭当前日志了。
完成了上一个步骤,就需要进行第二次控制文件事务,将刚刚关闭的REDO LOG 标识为ACTIVE,将新的当前REDO LOG标识为CURRENT,如果数据库处于归档模式,还要将老的日志组记录到控制文件归档列表记录中(在V$ARCHIVE 试图中科看到),并且通知归档进程对该日志文件进行归档。当所有的归档进程都处于忙状态的时候,并且归档进程总数没有超过log_archive_max_processes 的情况下,LGWR 还会生成一个新的归档进程来对老的日志文件进行归档。
这些操作完成后,LGWR 打开新的日志组的所有成员,并在文件头中记录下初始化信息。
这些完成后,LGWR 修改SGA 中的标志位,允许生成新的REDO LOG 信息。老的日志组目前还被标志位ACTIVE,当DBWR 完成了CHECKPOINT 所要求的写批量操作后,该日志组的状态会被标识为inactive。
从上述日志切换的步骤我们可以看出,日志切换还是有很多工作要做的,而且在日志切换开始到结束之间,日志的生成是被完全禁止的,因此在这个期间,对数据库的修改操作会被全部阻塞。这也是我们经常提到的:“日志切换是一种较为昂贵的操作”。既然日志切换十分昂贵,对系统性能的影响较大,那么我们就应该想办法减少日志切换的数量,提高日志切换的速度。
减少日志切换的数量我们可以从两个方面去考虑,一方面是减少日志的产生量,一方面是加大日志文件的大小。
对于减少日志产生量,常规的办法不外乎使用NOLOGGING 操作,使用BULK 操作、使用DIRECTPATH WRITE 操作等。不过大家要注意在归档模式下合非归档模式下,这些NOLOGGING 操作的效果是不同的。
有些DBA 担心加大REDO LOG 文件后会增加数据丢失的机会。的确,REDO LOG 文件越大,一个REDO LOG 文件所包含的REDO RECORD 的数量就越多,一旦整个REDO LOG文件丢失或者损坏,可能丢失的数据量就会增加。
实际上,整个REDO LOG 丢失的可能性极小,最主要的可能性是REDO LOG 文件被误删。如果存储出现故障,导致了REDO LOG 文件损坏,那么受影响的肯定是所有的REDO LOG 文件,而不是某一个REDO LOG 文件,无论REDO LOG 信息是存在一个REDO LOG 文件中还是存在2 个REDO LOG 文件中,其结果是完全一样的。
剩下一种情况就是最常见的情况了,就是服务器突然宕机,我们可以来分析一下服务器宕机这种情况,REDO LOG 文件的大小不同可能造成的数据丢失是否会不同。
首先我们要了解一下服务器宕机时可能丢失的数据可能是哪些,如果是已经提交的数据,CHECKPOINT已经推进到的部分,是已经被写入数据文件了,这部分数据是无论如何都不会丢失的,REDO LOG 是用来恢复最后一次CHECKPOINT 到宕机前被写入REDO LOG 文件的那部分数据。
由于REDO LOG 文件的写入是顺序的,因此无论这部分数据被写入到一个文件还是多个文件,并不影响这部分数据的恢复。因此我们可以看出,REDO LOG 文件大小和服务器宕机丢失数据的数量是无关的。
通过前面的分析我们应该已经了解到,系统故障时只有当整个REDO LOG 文件损坏时,REDO LOG 文件的大小才可能与丢失的数据量有关。在绝大多数情况下,加大REDO LOG 文件的大小并不会增加数据丢失的机会。因此我们在考虑REDO LOG 文件大小的时候,基本上可以忽略这个数据丢失的多少的问题。
不过在某些情况下,我们在需要加大REDO LOG 文件大小的时候,要适当的考虑,一是存在DATA GUARD 的情况下,为了减少FAILOVER 时的数据丢失量,我们不宜将REDO LOG 文件设置的过大。另外在存在CDC 或者流复制下游捕获的环境下,也需要考虑REDO LOG 文件大小和捕获延时的关系问题。
很多DBA 都受过教育,就是REDO LOG 切换的时间应该尽可能的不低于10-20 分钟,如果日志切换间隔低于这个值,就要考虑加大REDO LOG 文件的大小。事实上,没有任何铁律,只要日志切换并没有对系统的性能和安全产生严重的影响.