所有实例(对应并行数据服务器)执行数据库所有数据文件的一个CHECKPIONT操作,属于此实例的全部脏缓存区写入数据文件。
所有实例需要执行数据文件集的一个检查点操作,如使用热备份命令alter tablespace USERS begin backup,或表空间脱机命令alter tablespace USERS offline,将执行属于USERS表空间的所有数据文件的一个检查点操作。
获取CHECKPIONT记录信息的结构,此结构包括当前CHECKPIONT时间、活动线程、进行CHECKPIONT处理的当前线程、日志文件中恢复截止点的地址信息;
标识所有脏缓存区,当CHECKPIONT找到一个脏缓存区就将其标识为需要进行刷新,标识的脏缓存区由系统进程DBWR进行写操作,将脏缓存区的内容写入数据文件;
DBWR进程将所有脏缓存区写入磁盘后,设置一标志,标识已完成脏缓存区至磁盘的写入操作。系统进程LGWR与CKPT进程将继续进行检查,直至DBWR进程结束为止;
CHECKPIONT事件是数据库的一个很重要的内部事件,只有了解它的运行机制,才能很好的掌握数据库的内部运行,才能很好的掌握备份与恢复,也才能在紧急的时候解决必要的问题……
CHECKPIONT事件的触发,将使得数据库将已经修改的数据(脏数据)写到磁盘,同时还将修改控制文件和数据库头,同步它们的scn号,它的触发条件是:
当符合LOG_CHECKPOINT_TIMEOUT,LOG_CHECKPOINT_INTERVAL,fast_start_io_target,fast_start_mttr_target参数设置的时候
其实当检查点发生的时候,CKPT获取发生检查点时对应的SCN,通知DBWn要写到这个SCN为止,CKPT将最近一次(可能是上次也可能是上上次)DBWn成功完成写Dirty Buffer时对应的SCN更新到控制文件和数据文件头 (增量检查点时不写数据文件头)。至此检查点事件完成。剩下的工作就交给DBWn了。期间,CKPT检查checkpoint queue(也就是脏块链表)是否过长,如果是,则触发DBWn,DBWn将开始工作,他将一部分脏块写入数据文件,从而缩短checkpoint queue。但是为了恢复过程的迅速,CKPT进程以3秒的频率将DBWn写的进度反应到控制文件中,就是CKPT进程每三秒钟向控制文件写一次DBWn的执行情况,也就是把DBWn当前刚写完的dirty buffer对应的scn 写入数据文件头和控制文件。因此,可以看出,CKPT更新数据文件和控制文件,不是使用当前检查点的scn,而是使用上一次检查点过程中DBWn进程成功写完成dirty buffer队列中某个block 对应的scn 。
如果在DBWn写dirty buffer时候,发生掉电,则恢复过程肯定是:首先从控制文件中找到,上次检查点发生后最后成功写入那个block块对应的scn往后进行恢复。也就是CKPT进程在掉电前那最后一个三秒钟轮回,向控制文件写如的scn为恢复的前界限,往后进行恢复。
1)数据文件不处于热备份方式,此时ORACLE将不知道操作系统将何时读文件头,而备份拷贝在拷贝开始时必须具有检查点SCN;ORACLE在数据文件头中保留一个检查点的记数器,在正常操作中保证使用数据文件的当前版本,在恢复时防止恢复数据文件的错误版本;即使在热备份方式下,计数器依然是递增的;每个数据文件的检查点计数器,也保留在控制文件相对应数据文件项中。
2)检查SCN小于文件头中的检查点SCN的时候,这表明由检查点产生的改动已经写到磁盘上,在执行全局检查点的处理过程中,如果一个热备份快速检查点在更新文件头时,则可能发生此种情况。应该注意的是,ORACLE是在实际进行检查点处理的大量工作之前捕获检查SCN的,并且很有可能被一条象热备份命令 alter tablespace USERS begin backup进行快速检查点处理时的命令打断。
ORACLE在进行数据文件更新之前,将验证其数据一致性,当验证完成,即更新数据文件头以反映当前检查点的情况;未经验证的数据文件与写入时出现错误的数据文件都被忽略;如果日志文件被覆盖,则这个文件可能需要进行介质恢复,在这种情况下,ORACLE系统进程DBWR将此数据文件脱机。
脏缓存区用一个新队列链接,称为检查点队列。对缓存区的每一个改动,都有一个与其相关的重做值。检查点队列包含脏的日志缓存区,这些缓存区按照它们在日志文件中的位置排序,即在检查点队列中,缓存区按照它们的低重做值进行排序。需要注意的是,由于缓存区是依照第一次变脏的次序链接到队列中的,所以,如果在缓存区写出之前对它有另外的改动,链接不能进行相应变更,缓存区一旦被链接到检查点队列,它就停留在此位置,直到将它被写出为止。
ORACLE系统进程DBWR在响应检查点请求时,按照这个队列的低重做值的升序写出缓存区。每个检查点请求指定一个重做值,一旦DBWR写出的缓存区重做值等于或大于检查点的重做值,检查点处理即完成,并将记录到控制文件与数据文件。
由于检查点队列上的缓存区按照低重做值进行排序,而DBWR也按照低重做值顺序写出检查点缓存区,故可能有多个检查点请求处于活动状态,当DBWR写出缓存区时,检查位于检查点队列前端的缓存区重做值与检查点重做值的一致性,如果重做值小于检查点队列前缓存区的低重做值的所有检查点请求,即可表示处理完成。当存在未完成的活动检查点请求时,DBWR继续写出检查点缓存区。
四、SCN的管理方式
Oracle对SCN的管理,分为单节点和RAC两种方式:
1.单节点的instance中
单节点的instance中,SCN值存在SGA区,由system commit number latch保护。任何进程要得到当前的SCN值,都要先得到这个latch。
2.RAC/OPS环境中
Oracle通过排队机制(Enqueue)实现SCN在各并行节点之间的顺序增长。
具体有两种方法:
Lamport算法:
又称面包房算法,先来先服务算法。跟很多银行采用的排队机制一样。客户到了银行,先领取一个服务号。一旦某个窗口出现空闲,拥有最小服务号的客户就可以去空闲窗口办理业务。
Commit广播算法:
一有commit完成,最新的SCN就广播到所有节点中。
上述两种算法可以通过调整初始化参数max_commit_propagation_delay来切换。在多数系统 (除了Compaq Tur64 Unix)中,该参数的默认值都是700厘秒(centisecond),采用Lamport算法。如果该值小于100厘秒,Oracle就采用广播算法,并且记录在alert.log文件中。
五、SCN的种类
(1)Commit SCN
当用户提交commit命令后,系统将当前scn赋给该transaction。这些信息都反映在redo buffer中,并马上更新到redo log 文件里。
(2)Offline SCN
除了System tablespace以外的任何表空间,当我们执行SQL>alter tablespace … offline normal命令时,就会触发一个checkpoint,将内存中的dirty buffer写入磁盘文件中。Checkpoint完成后,数据文件头会更新checkpoint scn和offline normal scn值。其中数据库文件头的checkpoint scn值可通过查询列x$kccfe.fecps得到。
如果执行SQL>alter tablespace …offline命令时采用temporary或 immediate选项,而不用normal选项时,offline normal scn会被设成0。这样当数据库重启后通过resetlog方式打开时,该表空间就无法再改回在线状态。
(3)Checkpoint SCN
当数据库内存的脏数据块(dirty blocks)写到各数据文件中时,就发生一次checkpoint。数据库的当前checkpoint scn值存在x$kccdi.discn中。Checkpoint scn在数据库恢复中起着至关重要的作用。无论你用何种办法恢复数据库,只有当各个数据库文件的checkpoint scn都相同时,数据库才能打开。
虽然参数“_allow_resetlogs_corruption”可以在checkpoint scn不一致时强制打开数据库,但是这样的数据库在open后必须马上作全库的export,然后重建数据库并import数据。
(4)Resetlog SCN
数据库不完全恢复时,在指定时间点后的scn都无法再应用到数据库中。Resetlog时的scn就被设成当前数据库scn,redo log也会被重新设置。
(5)Stop SCN
Stop scn记录在数据文件头上。当数据库处在打开状态时,stop scn被设成最大值0xffff.ffffffff。在数据库正常关闭过程中,stop scn被设置成当前系统的最大scn值。在数据库打开过程中,Oracle会比较各文件的stop scn和checkpoint scn,如果值不一致,表明数据库先前没有正常关闭,需要做恢复。
(6)High and Low SCN
Oracle的Redo log会顺序纪录数据库的各个变化。一组redo log文件写满后,会自动切换到下一组redo log文件。则上一组redo log的high scn就是下一组redo log的low scn。
在视图v$log_history中,sequence#代表redo log的序列号,first_change#表示当前redo log的low scn,列next_change#表示当前redo log的high scn。
SQL> col recid format 9999
SQL> col requence# format 9999
SQL> col first_change# format 9,999,999,999,999
SQL> col next_change# format 9,999,999,999,999
SQL> select recid,sequence#,first_change#,next_change# from v$log_history where rownum<6;
RECID SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
----- ---------- ------------------ ------------------
484 484 1,928,645,840,091 1,928,645,840,436
485 485 1,928,645,840,436 1,928,645,840,636
486 486 1,928,645,840,636 1,928,778,045,209
487 487 1,928,778,045,209 1,929,255,480,725
488 488 1,929,255,480,725 1,930,752,214,033
六、SCN号与oracle数据库恢复的关系
SCN号与oracle数据库恢复过程有着密切的关系&#xff0c;只有很好地理解了这层关系&#xff0c;才能深刻地理解恢复的原理&#xff0c;从而才能很好地解决这方面的问题。
SCN与CHECKPOINT CKPT进程在checkpoint发生时&#xff0c;将当时的SCN号写入数据文件头和控制文件&#xff0c;同时通知DBWR进程将数据块写到数据文件。
CKPT进程也会在控制文件中记录RBA(redo block address),以标志Recovery需要从日志中哪个地方开始。与checkpoint相关的SCN号有四个&#xff0c;其中三个存在控制文件中&#xff0c;一个存放在数据文件头中。
这四个分别是&#xff1a;
&#xff08;1&#xff09;System Checkpoint SCN
当checkpoint完成后&#xff0c;ORACLE将System Checkpoint SCN号存放在控制文件中。
我们可以通过下面SQL语句查询&#xff1a;
select checkpoint_change# from v$database;
&#xff08;2&#xff09;Datafile Checkpoint SCN
当checkpoint完成后&#xff0c;ORACLE将Datafile Checkpoint SCN号存放在控制文件中。
我们可以通过下面SQL语句查询所有数据文件的Datafile Checkpoinnt SCN号。
select name,checkpoint_change# from v$datafile;
&#xff08;3&#xff09;Start SCN号
ORACLE将Start SCN号存放在数据文件头中。
这个SCN用于检查数据库启动过程是否需要做media recovery.
我们可以通过以下SQL语句查询&#xff1a;
select name,checkpoint_change# from v$datafile_header;
&#xff08;4&#xff09;End SCN号
ORACLE将End SCN号存放在控制文件中。
这个SCN号用于检查数据库启动过程是否需要做instance recovery.
我们可以通过以下SQL语句查询&#xff1a;
select name,last_change# from v$datafile;
在数据库正常运行的情况下&#xff0c;对可读写的&#xff0c;online的数据文件&#xff0c;该SCN号为NULL.
试验内容如下&#xff1a;
在执行检查点进程之前SCN号如下&#xff1a;
&#xff08;1&#xff09;System Checkpoint SCN
SQL>select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
4609061
&#xff08;2&#xff09;Datafile Checkpoint SCN
SQL>select name,checkpoint_change# from v$datafile;
NAME CHECKPOINT_CHANGE#
------------------- ------------------
D:\BOCO\OPENVIEW\ORADATA\OPENVIEW\user01.dbf 4609061
&#xff08;3&#xff09;Start SCN
SQL>select name,checkpoint_change# from v$datafile_header;
NAME CHECKPOINT_CHANGE#
------------------- ------------------
D:\BOCO\OPENVIEW\ORADATA\OPENVIEW\user01.dbf 4609061
&#xff08;4&#xff09;End SCN
SQL>select name,last_change# from v$datafile;
执行alter system checkpoint后的SCN号如下&#xff1a;
&#xff08;1&#xff09;System Checkpoint SCN
SQL>select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
4609630
&#xff08;2&#xff09;Datafile Checkpoint SCN
SQL>select name,checkpoint_change# from v$datafile;
NAME CHECKPOINT_CHANGE#
------------------- ------------------
D:\BOCO\OPENVIEW\ORADATA\OPENVIEW\user01.dbf 4609630
Start SCN
SQL>select name,checkpoint_change# from v$datafile_header;
NAME CHECKPOINT_CHANGE#
------------------- ------------------
D:\BOCO\OPENVIEW\ORADATA\OPENVIEW\user01.dbf 4609630
End SCN
SQL>select name,last_change# from v$datafile;
SCN不连续原因可能如下&#xff1a;
1.当发生日志组切换的时候
2.当符合LOG_CHECKPOINT_TIMEOUT&#xff0c;LOG_CHECKPOINT_INTERVAL&#xff0c;fast_start_io_target,fast_start_mttr_target参数设置的时候
3.当运行ALTER SYSTEM SWITCH LOGFILE的时候
4.当运行ALTER SYSTEM CHECKPOINT的时候
5.当运行alter tablespace XXX begin backup&#xff0c;end backup的时候
6.当运行alter tablespace ,datafile offline的时候;
七、SCN号与数据库启动
在数据库启动过程中&#xff0c;当System Checkpoint SCN、Datafile Checkpoint SCN和Start SCN号都相同时&#xff0c;数据库可以正常启动&#xff0c;不需要做media recovery.三者当中有一个不同时&#xff0c;则需要做media recovery。
如果在启动的过程中&#xff0c;End SCN号为NULL&#xff0c;则需要做instance recovery。ORACLE在启动过程中首先检查是否需要media recovery&#xff0c;然后再检查是否需要instance recovery。
八、SCN号与数据库关闭
如果数据库的正常关闭的话&#xff0c;将会触发一个checkpoint&#xff0c;同时将数据文件的END SCN号设置为相应数据文件的Start SCN号。
当数据库启动时&#xff0c;发现它们是一致的&#xff0c;则不需要做instance recovery。在数据库正常启动后&#xff0c;ORACLE会将END SCN号设置为NULL。
如果数据库异常关闭的话&#xff0c;则END SCN号将为NULL.
九、为什么需要System checkpoint SCN号与Datafile Checkpoint SCN号&#xff1f;
为什么ORACLE会在控制文件中记录System checkpoint SCN号的同时&#xff0c;还需要为每个数据文件记录Datafile Checkpoint SCN号&#xff1f;
原因有二&#xff1a;
1.对只读表空间&#xff0c;其数据文件的Datafile Checkpoint SCN、Start SCN和END SCN号均相同。这三个SCN在表空间处于只读期间都将被冻结。
2.如果控制文件不是当前的控制文件&#xff0c;则System checkpoint会小于Start SCN或END SCN号。记录这些SCN号&#xff0c;可以区分控制文件是否是当前的控制文件。
十、Recovery database using backup controlfile
以下条件需要使用using backup controlfile
1&#xff09;使用备份控制文件
2&#xff09;重建resetlogs控制文件,如果重建立noresetlogs不必要使用using backup controlfile
当有一个Start SCN号超过了System Checkpoit SCN号时&#xff0c;则说明控制文件不是当前的控制文件&#xff0c;因此在做recovery时需要采用using backup controlfile。这是为什么需要记录System Checkpoint SCN的原因之一。
这里需要一提的是&#xff0c;当重建控制文件的时候&#xff0c;System Checkpoint SCN为0&#xff0c;Datafile Checkpoint SCN的数据来自于Start SCN。
根据上述的描述&#xff0c;此时需要采用using backup controlfile做recovery。
十一、alter database open resetlog
指定RESETLOGS将重设当前LOG sequence number为1&#xff0c;抛弃所有日志信息。
以下条件需要使用resetlog
1&#xff09;在不完全恢复&#xff08;介质恢复&#xff09;
2&#xff09;使用备份控制文件
使用resetlogs打开数据库后无必完整地备份一次数据库。
十二、create controlfile resetlogs/noresetlogs
1&#xff09;用noresetlogs重建控制文件时&#xff0c;控制文件中 datafile checkpoint来自online logs中的current log头
2&#xff09;用resetlogs重建控制文件时&#xff0c;控制文件中datafile checkpoint来自各数据文件头。
&#xff08;注&#xff1a;本文引自&#xff1a;http://19880614.blog.51cto.com/4202939/1195298&#xff09;