dbsnak在微博里这样描述等待事件log file sync和log file parallel write的关系:
前台进程a通知LGWR要刷log buffer了,这时候a就开始等待log file sync,LGWR接到a的请求后开始等待OS把log buffer写回redo log,这时候LGWR就开始等待log file parallel write,OS写完了通知LGWR,中止log file parallel write等待,接着LGWR通知a,中止log file sync等待 --- 这就是上述两种等待的区别。
----------------------------------------------------------------------------------
以上不完全:
Log file parallel write
log file parallel write 事件是LGWR进程专属的等待事件,发生在LGWR将log_buffer中的重做日志信息写入联机重做日志文件组的成员文件,LGWR在该事件上等待该写入过程的完成。
由用户提交和回滚初始化的写入称为同步写入;其余的写入成为后台写入。log file sync等待只和同步写入有关。换句话说,用户进程可能正在处理一个大型的事务并生成许多触发LGWR以执行后台写入的大量重做条目,但用户会话从来不需要等待后台写入的完成。然而,一旦用户会话提交或回滚它的事务且_WAIT_FOR_SYNC参数是TRUE时,进程提交LGWR并在log file sync事件上等待LGWR将当前重做条目(包括提交标记)刷新到日志文件。在这种日志同步期间,LGWR进程在log file parallel write事件上等待同步写入的完成,同时用户会话在log file sync事件上等待同步进程的完成。
----------------------------------------------------------------------------------
有上面这个形象的例子,可以明白等待事件log file sync和log file parallel write是同时存在的,均是等待LGWR进程将log buffer中的redo entries写入online redo log的完成。
当一个前台进程(或用户会话)进行提交(commit)或回滚(rollback)时,这个会话的redo信息就需要被刷入redo log file中。且该回话会通知LGWR将所有需要的redo entries写入redo log file。当LGWR写入完成后,又会返回用户会话一个确认信息,以表明redo entries已全部安全的写入到了磁盘。
log file sync的参数有:
P1 = buffer#
在log buffer中,所有变更到这个缓冲号的重做条目都必须被刷新到磁盘,且保证所有已提交的事务被确认写入,即使发生instance crash,也不会影响到已提交的事务,因此log file sync等待事件就是等待直到缓冲号为buffer#的redo entries均被写入到了磁盘。
P2 = Not used
P2 = Not used
通常发生log file sync等待事件是由于LGWR写入缓慢或者应用程序的提交操作过于频繁。可以通过如下措施帮助减少log file sync等待:
1、将online redo log file放在最快的磁盘上,例如该磁盘不允许配置RAID 5,因为RAID 5对于频繁写入操作性能较差。
2、采用批量提交的方式。
3、在Oracle 10gR2中,commit命令增加了WRITE子句来控制在commit操作期间,redo写入redo log file的方式和程度。WRITE子句的作用只是为了提高性能,安全方面会被降低,因为可能会造成提交的事务却没被写入redo log file而丢失数据。
Oracle文档中是这样描述commit语句的write子句的:
COMMIT;
COMMIT WRITE WAIT; --> The commit command is synchronous. It doesn't return until the relevant redo information is written to the online redo log.
COMMIT WRITE NOWAIT; --> The commit command is asynchronous. It can return before the relevant redo information is written to the online redo log.
COMMIT WRITE BATCH; --> The commit command is synchronous. It doesn't return until the relevant redo information is written to the online redo log.
COMMIT WRITE IMMEDIATE; --> The commit "prods" the LGWR process by sending a message, so that the redo is written immediately to the redo logs.
上面这种方式是要通过修改程序代码实现的,如果想避免修改程序代码,也可以在session级别或system级别通过参数COMMIT_WRITE实现,如:
SQL> alter [system | session] set COMMIT_WRITE=’IMMEDIATE,NOWAIT’;
也可以通过触发器来监视当某用户的应用程序运行时进行COMMIT_WRITE参数的设置:
SQL> CREATE OR REPLACE TRIGGER sys.global_commit_session_settings ALTER LOGON ON <your application_username>.SCHEMA
BEGIN
execute immediate ‘alter session set COMMIT_WRITE=”IMMEDIATE,NOWAIT”’
END;
/
需要注意的是:如果使用了此选项,一旦数据库实例失败(CRASH),尽管是已被提交的事务,也会丢失没有被写入到redo log file中的数据,请慎用。
4、使用NOLOGGING或UNRECOVERABLE选项。