oracle event ----- Log file sync

来源:互联网 发布:全国交通道路网络数据 编辑:程序博客网 时间:2024/06/05 02:47

   ORACLE在日志缓存区中记录事务和块的变化信息,当满足特定条件时,有LGWR进程将缓冲区中的内容写入到redo log文件。触发LGWR写动作的事件主要包括: 

  1. 用户提交
  2. 有1/3重做日志缓冲区未被写入磁盘 
  3. 有大于1M的重做日志缓冲区未被写入磁盘 
  4. 3秒超时 
  5. DBWR 需要写入的数据的SCN大于LGWR记录的SCN,DBWR 触发LGWR写入。
    我们可以将LGWR的写入分为两类:同步写入和非同步写入。同步写入的触发事件需要同步等待LGWR的写入完成,如用户的提交和回滚,必须在对于日志写入日志文件后才会返回完成。log file sync事件仅仅与同步写入相关,总结如下:
  1. 用户提交(可以通过v$sesstat视图中的user commits统计信息)
  2. DDL操作(造成递归的事务提交)
  3. 递归数据字典更新(例如,向表中插入大量数据然后回滚,此时与段有关的信息是持久存储的,并没有回滚)
  4. 用户回滚操作(可以通过v$sesstat视图中的user rollbacks统计信息)
  5. 由于错误造成的事务回滚,如kill session (可以通过v$sesstat视图中的transaction rollbacks统计信息)
    下面以用户提交操作为例阐述log file sync事件的工作机制。


    上图非常清楚的表述了单实例模式下用户提交操作的处理过程,从图中可以看出正常情况下log file sync事件的大部分时间被log file parallel write占据,除此之外,还有一部分时间消耗在cpu调度上面,如下图:

从上图可以看出,如果cpu资源紧张也会造成log file sync等待时间的延长。

     在RAC数据库中为了一致性读,需要将Commit SCN同步/传播到所有的节点上。SCN同步/传播的主要方法有两种:Lamport SCN 和 immediate commit propagation (BOC). 10gR1 及以下版本默认使用Lamport SCN,Lamport SCN方式即一个节点上的commit SCN 不保证立刻同步/传播到所有节点,也就是说可能延时同步/传播,对于一些实时性要求高的RAC数据库Lamport SCN方式是不可取的。如果希望commit SCN 立刻同步/传播到所有节点,手动修改参数MAX_COMMIT_PROPAGATION_DELAY=1。从10gR2开始默认使用immediate commit propagation (BOC),BOC即一个节点上的commit SCN 立刻同步/传播到所有节点。

    BOC模式下,用户提交的处理过程:

  1.  user session 执行提交(commit),user session会通知LGWR进程将redo buffer中的信息写入到redo log file。
  2.  LGWR进程收到user session通知后,将redo buffer中的信息写入redo log file,同时LGWR 将COMMIT SCN 同步/传播给远程的数据库实例的LMS 进程。
  3. 远程数据库实例的LMS将commit SCN同步到本地SCN,然后通知commit实例的LMS,表示SCN 同步已经完成。
  4. 当commit 实例的LMS接收到所有远程数据库实例的LMS的通知后,commit 实例的LMS再通知本地的LGWR 所有节点SCN同步已经完成。
  5. LGWR 在完成了IO 操作和LMS进程通知后,LGWR通知user session commit 成功。user session在没有收到LGWR通知前,一直处于等待log file sync

    至此,我们不难看出来导致'log file sync' 等待事件的主要原因有:

  1. 磁盘IO 慢导致LGWR进程将redo buffer中的信息写入到redo log file速度慢。
  2. user session commit过于频繁。
  3. 本地或者远程服务器CPU资源不足,导致LMS和/或者LGWR不能及时得到CPU调度,不能正常工作。
  4. RAC私有网络性能差,导致LMS同步commit SCN慢。
  5. ORACLE BUG
  6. 过大的日志缓冲区也可能延长log file sync等待。大型的日志缓冲区减少后台写入的数量,允许LGWR变得懒惰,并导致更多的重做条目堆积在日志缓冲区中。同时可以调整参数_LOG_IO_SIZE参数,其默认值是LOG_BUFFER的1/3或1MB,取两者之中较小的值

    解决的方法:
  1. 提高LGWR性能,尽量使用快速磁盘,不要把redo log file存放在raid 5的磁盘上
  2. 使用批量提交
  3. 适当使用NOLOGGING/UNRECOVERABLE等选项
  4.  安装OSWatcher 定位CPU使用率高的进程
  5. 采用专用网络,正确设置网络UDP buffer参数
  6. 安装最新版本数据库避免bug,具体bug修复的版本参考文档

    诊断小贴士:
  1. 如果log file sync 的等待时间与log file parallel write的时间基本相同,则可能是由于IO问题导致的log file sync.
  2. 如果在LGWR TRACE文件中出现类似 Warning: log write time 1000ms, size 2KB字样,则可能是io问题(10.2.0.4中引入,可使用event :10468 level 4 屏蔽掉)
  3. 使用user commits;user rollback等统计信息查看是否提交或者回滚次数过多,可以使用如下公式计算每次写入redologfile的数据大小。avg.redo write size = (Redo block written/redo writes)*512 bytes
  4. 如果用户提交频繁引起log file sync事件,那么可能伴随着redo writing的latch竞争

    如果对事务的一致性要求并不是太严格,允许实例失败后部分数据的丢失,我们可以使用commit命令的write子句来控制commit提交操作的行为:
    commit write <wait|nowait> <batch|immediate>
    除此之外,我们也可使用commit_write参数,在11g中,commit_write不再建议被使用,而是用commit_logging和commit_wait来替代.下面是部分实例:
Commit Write BATCH – Informations of redo logs are  buffered. Commit Write IMMEDIATE- LGWR process by send a message, so that the redo logs can write as soon as possible. Commit Write NOWAIT – This is  an asynchronous process.  it will return before the reqired redo details is written to the online redo log. Commit Write WAIT – This will synchronous the operation. It will not return until the required redo logs is written to the online redo log file. ALTER SYSTEM  SET COMMIT_WRITE='BATCH,WAIT';ALTER SYSTEM  SET COMMIT_WRITE='BATCH,NOWAIT';ALTER SYSTEM  SET COMMIT_WRITE='IMMEDIATE,WAIT';ALTER SYSTEM  SET COMMIT_WRITE='IMMEDIATE,NOWAIT';ALTER SYSTEM  SET COMMIT_WRITE='WAIT';ALTER SYSTEM  SET COMMIT_WRITE='NOWAIT';ALTER SYSTEM  SET COMMIT_WRITE='IMMEDIATE';ALTER SYSTEM  SET COMMIT_WRITE='BATCH';  ALTER session  SET COMMIT_WRITE='BATCH,WAIT';ALTER session  SET COMMIT_WRITE='BATCH,NOWAIT';ALTER session  SET COMMIT_WRITE='IMMEDIATE,WAIT';ALTER session  SET COMMIT_WRITE='IMMEDIATE,NOWAIT';ALTER session  SET COMMIT_WRITE='WAIT';ALTER session  SET COMMIT_WRITE='NOWAIT';ALTER session  SET COMMIT_WRITE='IMMEDIATE';ALTER session  SET COMMIT_WRITE='BATCH';


原创粉丝点击