MTTR-Mean Time To Recover
MTBF-Mean Time Between Failures
先要明白一些概念:
日志文件中的信息为了当系统出现failure时,保证事务可以恢复。当用户事务完成发出commit时,总是先等待LGWR进程将事务所需的redo信息写到日志文件(之前可能在redo buffer中)后,才会收到commit complete信息。
DBWR进程总是比LGWR进程写的速度慢(DBWR进程是随机写,LGWR进程是顺序写,随机写比顺序写要慢)
当DBWR进程要将缓存区中的信息写入到数据文件时,会先通知LGWR进程将事务相关的redo信息写入到日志文件。
SCN可以理解为一个标签,ORACLE对数据库中的每个操作都打上一个标签。这个标签是顺序增加的。永远不会归0(除非数据库重建)
CHECKPOINT是ORACLE为了记录哪些数据已经被写入到数据文件中。
CHECKPOINT的作用就是要保证当checkpoint发生时,这个checkpoint SCN之前的数据都要由DBWR写入到数据文件中,而在DBWR写之前,又会触发LGWR进程将相关的redo信息写入到日志文件中。这样,checkpoint完成后,发生instance failure时就不再需要恢复这个checkpoint SCN前的信息.
理解实例恢复的相关信息:
Instance Recovery所需要的信息,就是最近一次checkpoint之后到日志文件结尾的这些redo信息。
因为checkpoint之前的数据都已经一致性地写入到数据文件中了,而之后的数据可能有一部分已经写进数据文件,而有一部分没有写进数据文件。
Instance Recovery所需要的时间,将数据文件 从最近一次checkpoint开始,恢复到控制文件中记录的这个数据文件的最后一个SCN值为止,应用这两者之间redo信息的时间就是instance recovery所要花费的时间。
实例恢复的调整:
由上面的信息可以总结出,实例恢复最关键的问题的就是最近一次CHECKPOINT发生的时间,以及CHECKPOINT发生的频率。只有确认了最近一次CHECKPOIN发生的时间点,才能确定恢复所需的redo信息,以及恢复所要花费的时间。
对于instance recovery花费时间的调优,就是对参数FAST_START_MTTR_TARGE的调整,单位“秒”,大值为3600秒。
也就是说FAST_START_MTTR_TARGET这个参数的设置会直接影响到checkpoint发生的频率。
FAST_START_MTTR_TARGE所设置的时间就是用户希望数据库用在instance recovery的时间。也就是从应用最近一次checkpoint到日志信息最后这两个点之间redo信息所要花费的时间。
MTTR设置的时间过小的话,会造成系统checkpoint过于频繁,而发生checkpoint时就要DBWR,LGWR等进程写数据文件,产生物理IO,久而久之,数据库性能会越来越慢;
MTTR设置的时间过大的话,当实例失败时,instance recover所花费的时间就会过长。
从10g开始,数据库可以实现自动调整,如果FAST_START_MTTR_TARGET=0时,可以从alert里面看到如下信息:
MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set
此时,数据库会根据负载自动调整checkpoint发生的频率。
如果要严格要求instance recovery时间的话,就设置FAST_START_MTTR_TARGET参数,如果不是那么严格的话,建议用10g的自动调整。
5.4.2.5 实例恢复的原理
前面我们讲到过,当数据库突然崩溃,而还没有来得及将buffer cache里的脏数据块刷新到数据文件里,同时在实例崩溃时正在运行着的事务被突然中断,则事务为中间状态,也就是既没有提交也没有回滚。这时数据文件里的内容不能体现实例崩溃时的状态。这样关闭的数据库是不一致的。
下次启动实例时,Oracle会由SMON进程自动进行实例恢复。实例启动时,SMON进程会去检查控制文件中所记录的、每个在线的、可读写的数据文件的END SCN号。数据库正常运行过程中,该END SCN号始终为空,而当数据库正常关闭时,会进行完全检查点,并将检查点SCN号更新该字段。而崩溃时,Oracle还来不及更新该字段,则该字段仍然为空。当SMON进程发现该字段为空时,就知道实例在上次没有正常关闭,于是由SMON进程就开始进行实例恢复了。
SMON进程进行实例恢复时,会从控制文件中获得检查点位置。于是,SMON进程到联机日志文件中,找到该检查点位置,然后从该检查点位置开始往下,应用所有的重做条目,从而在buffer cache里又恢复了实例崩溃那个时间点的状态。这个过程叫做前滚,前滚完毕以后,buffer cache里既有崩溃时已经提交还没有写入数据文件的脏数据块,也还有事务被突然终止,而导致的既没有提交又没有回滚的事务所弄脏的数据块。
前滚一旦完毕,SMON进程立即打开数据库。但是,这时的数据库中还含有那些中间状态的、既没有提交又没有回滚的脏块,这种脏块是不能存在于数据库中的,因为它们并没有被提交,必须被回滚。打开数据库以后,SMON进程会在后台进行回滚。
有时,数据库打开以后,SMON进程还没来得及回滚这些中间状态的数据块时,就有用户进程发出读取这些数据块的请求。这时,服务器进程在将这些块返回给用户之前,由服务器进程负责进行回滚,回滚完毕后,将数据块的内容返回给用户。
Oracle提供了初始化参数fast_start_mttr_target让我们指定完成实例恢复所花费的时间(该时间只包括前滚并打开数据库的时间,不包括回滚的时间),该参数以秒为单位。比如我们设置该参数为30,表示如果发生实例崩溃,那么下次重新启动时,数据库最多用30秒的时间完成前滚,并打开数据库。在数据库运行过程中,就会根据该时间,来估算30秒大致对应多少量的重做记录,这实际上就决定了检查点位置,如图5-8所示。
图5-8 检查点队列3 |
图5-8中的红色竖线就是检查点位置。Oracle应用完检查点位置以后所有的重做记录所花费的时间就是 fast_start_mttr_target所指定的时间。也就是说,检查点位置以后的重做记录所对应的脏块会被留在检查点队列上,而不被DBWn写入数据文件。因此,该参数越大,说明要应用的重做记录就越多,那么留在检查点队列上的脏块就越多,也就说明DBWn写脏块越不频繁,占用I/O越少,那么前台用户查询语句的I/O就能够越快地被响应。但是实例恢复的时间也会越长。反之,该参数越小,说明要应用的重做记录就越少,那么留在检查点队列上的脏块就越少,也就说明DBWn写脏块越频繁,因而占用I/O越多,那么前台用户查询语句的I/O就不能较快地被响应。但是实例恢复的时间会更短。