深入了解SCN

 参考:

2.10. 深入了解SCN
2.10.1. SCN的概念。。。

 

SCN是顺序递增的一个数字,在Oracle 中用来标识数据库的每一次改动,及其先后顺序。SCN的最大值是0xffff.ffffffff。

2.10.2. SCN的管理方式

Oracle对SCN的管理,分为单节点和RAC两种方式。
单节点的instance中
单节点的instance中,SCN值存在SGA区,由system commit number latch保护。任何进程要得到当前的SCN值,都要先得到这个latch。
RAC/OPS环境中
Oracle通过排队机制(Enqueue)实现SCN在各并行节点之间的顺序增长。具体有两种方法:
Lamport算法:又称面包房算法,先来先服务算法。跟很多银行采用的排队机制一样。客户到了银行,先领取一个服务号。一旦某个窗口出现空闲,拥有最小服务号的客户就可以去空闲窗口办理业务。
Commit广播算法:一有commit完成,最新的SCN就广播到所有节点中。
上述两种算法可以通过调整初始化参数max_commit_propagation_delay来切换。在多数系统 (除了Compaq Tur64 Unix)中,该参数的默认值都是700厘秒(centisecond),采用Lamport算法。如果该值小于100厘秒,Oracle就采用广播算法,并且记录在alert.log文件中。

2.10.3. 几种重要的SCN

Commit SCN
    当用户提交commit命令后,系统将当前scn赋给该transaction。这些信息都反映在redo buffer中,并马上更新到redo log 文件里。

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方式打开时,该表空间就无法再改回在线状态。

Checkpoint SCN
    当数据库内存的脏数据块(dirty blocks)写到各数据文件中时,就发生一次checkpoint。数据库的当前checkpoint scn值存在x$kccdi.discn中。Checkpoint scn在数据库恢复中起着至关重要的作用。无论你用何种办法恢复数据库,只有当各个数据库文件的checkpoint scn都相同时,数据库才能打开。
虽然参数“_allow_resetlogs_corruption”可以在checkpoint scn不一致时强制打开数据库,但是这样的数据库在open后必须马上作全库的export,然后重建数据库并import数据。

Resetlog SCN
    数据库不完全恢复时,在指定时间点后的scn都无法再应用到数据库中。Resetlog时的scn就被设成当前数据库scn,redo log也会被重新设置。

Stop SCN
    Stop scn记录在数据文件头上。当数据库处在打开状态时,stop scn被设成最大值0xffff.ffffffff。在数据库正常关闭过程中,stop scn被设置成当前系统的最大scn值。在数据库打开过程中,Oracle会比较各文件的stop scn和checkpoint scn,如果值不一致,表明数据库先前没有正常关闭,需要做恢复。

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

2.10.4. SCN号与oracle数据库恢复的关系

    SCN号与oracle数据库恢复过程有着密切的关系,只有很好地理解了这层关系,才能深刻地理解恢复的原理,从而才能很好地解决这方面的问题。
SCN与CHECKPOINT CKPT进程在checkpoint发生时,将当时的SCN号写入数据文件头和控制文件,同时通知DBWR进程将数据块写到数据文件。
CKPT进程也会在控制文件中记录RBA(redo block address),以标志Recovery需要从日志中哪个地方开始。与checkpoint相关的SCN号有四个,其中三个存在控制文件中,一个存放在数据文件头中。
这四个分别是:

1.System Checkpoint SCN
    当checkpoint完成后,ORACLE将System Checkpoint SCN号存放在控制文件中。我们可以通过下面SQL语句查询:
select checkpoint_change# from v$database;

2.Datafile Checkpoint SCN

    当checkpoint完成后,ORACLE将Datafile Checkpoint SCN号存放在控制文件中。我们可以通过下面SQL语句查询所有数据文件的Datafile Checkpoinnt SCN号。
select name,checkpoint_change# from v$datafile;

3.Start SCN号
    ORACLE将Start SCN号存放在数据文件头中。
    这个SCN用于检查数据库启动过程是否需要做media recovery.
    我们可以通过以下SQL语句查询:
    select name,checkpoint_change# from v$datafile_header;
   
4.End SCN号
    ORACLE将End SCN号存放在控制文件中。
    这个SCN号用于检查数据库启动过程是否需要做instance recovery.
    我们可以通过以下SQL语句查询:
    select name,last_change# from v$datafile;
    在数据库正常运行的情况下,对可读写的,online的数据文件,该SCN号为NULL.
   
我们作个小的试验,内容如下:
在执行检查点进程之前SCN号如下:
System Checkpoint SCN 4609061
--select checkpoint_change# from v$database;
Datafile Checkpoint SCN 4609061
--select name,checkpoint_change# from v$datafile;
Start SCN 4609061
--select name,checkpoint_change# from v$datafile_header;
End SCN 空
--select name,last_change# from v$datafile;
执行alter system checkpoint。后的SCN号如下:
System Checkpoint SCN 4609630
--select checkpoint_change# from v$database;
Datafile Checkpoint SCN 4609630
--select name,checkpoint_change# from v$datafile;
Start SCN 4609630
--select name,checkpoint_change# from v$datafile_header;
End SC 空
--select name,last_change# from v$datafile;
SCN不连续原因可能如下:

    1.当发生日志组切换的时候
    2.当符合LOG_CHECKPOINT_TIMEOUT,LOG_CHECKPOINT_INTERVAL,fast_start_io_target,fast_start_mttr_target参数设置的时候
    3.当运行ALTER SYSTEM SWITCH LOGFILE的时候
    4.当运行ALTER SYSTEM CHECKPOINT的时候
    5.当运行alter tablespace XXX begin backup,end backup的时候
    6.当运行alter tablespace ,datafile offline的时候;

2.10.4.1. SCN号与数据库启动
    在数据库启动过程中,当System Checkpoint SCN、Datafile Checkpoint SCN和Start SCN号都相同时,数据库可以正常启动,不需要做media recovery.三者当中有一个不同时,则需要做media

recovery。如果在启动的过程中,End SCN号为NULL,则需要做instance recovery。ORACLE在启动过程中首先检查是否需要media recovery,然后再检查是否需要instance recovery。
2.10.4.2. SCN号与数据库关闭
    如果数据库的正常关闭的话,将会触发一个checkpoint,同时将数据文件的END SCN号设置为相应数据文件的Start SCN号。
当数据库启动时,发现它们是一致的,则不需要做instance recovery。在数据库正常启动后,ORACLE会将END SCN号设置为NULL。如果数据库异常关闭的话,则END SCN号将为NULL.
2.10.4.3. 为什么需要System checkpoint SCN号与Datafile Checkpoint SCN号
    为什么ORACLE会在控制文件中记录System checkpoint SCN号的同时,还需要为每个数据文件记录Datafile Checkpoint SCN号?

原因有二:
    1.对只读表空间,其数据文件的Datafile Checkpoint SCN、Start SCN和END SCN号均相同。这三个SCN在表空间处于只读期间都将被冻结。
    2.如果控制文件不是当前的控制文件,则System checkpoint会小于Start SCN或END SCN号。记录这些SCN号,可以区分控制文件是否是当前的控制文件。

2.10.4.4. Recovery database using backup controlfile
    当有一个Start SCN号超过了System Checkpoit SCN号时,则说明控制文件不是当前的控制文件,因此在做recovery时需要采用using backup controlfile。这是为什么需要记录SystemCheckpoint SCN的

原因之一。
这里需要一提的是,当重建控制文件的时候,System Checkpoint SCN为0,Datafile Checkpoint SCN的数据来自于Start SCN。根据上述的描述,此时需要采用using backup controlfile做recovery。

checkpoint事件是数据库的一个很重要的内部事件,只有了解它的运行机制,才能很好的掌握数据库的内部运行,才能很好的掌握备份与恢复,也才能在紧急的时候解决必要的问题……

checkpoint事件的触发,将使得数据库将已经修改的数据(脏数据)写到磁盘,同时还将修改控制文件和数据库头,同步它们的scn号,它的触发条件是:

当发生日志组切换的时候
当符合LOG_CHECKPOINT_TIMEOUT,LOG_CHECKPOINT_INTERVAL,fast_start_io_target,fast_start_mttr_target参数设置的时候
当运行ALTER SYSTEM SWITCH LOGFILE的时候
当运行ALTER SYSTEM CHECKPOINT的时候
当运行alter tablespace XXX begin backup,end backup的时候
当运行alter tablespace ,datafile offline的时候;
运行alter tablespace、datafile offline的时候,它们存在着一定的区别:

alter datafile offline: 在offline、online的时候,系统将不会修改所有datafile的scn
alter tablespace offline:offline的事件,就会修改scn号;在online的时候,系统也将修改该ts下的所有datafile的scn
这正是为什么online datafile需要recovery,而online tablespace就不需要

其实当检查点发生的时候,CKPT获取发生检查点时对应的SCN,通知DBWn要写到这个SCN为止,CKPT将最近一次(可能是上次也可能是上上次)DBWn成功完成写Dirty Buffer时对应的SCN更新到控制文件和数据文件头 (增量检查点时不写数据文件头)。至此检查点事件完成。剩下的工作就交给DBWn了。期间,CKPT检查checkpoint queue(也就是脏块链表)是否过长,如果是,则触发DBWn,DBWn将开始工作,他将一部分脏块写入数据文件,从而缩短checkpoint queue。但是为了恢复过程的迅速,ckpt进程以3秒的频率将dbwr 写的进度反应到控制文件中,就是ckpt进程每三秒钟向控制文件写一次dbwr的执行情况,也就是把dbwr当前刚写完的dirty buffer对应的scn 写入数据文件头和控制文件。因此,可以看出,ckp更新数据文件和控制文件,不是使用当前检查点的scn,而是使用上一次检查点过程中dbwr进程成功写完成dirty buffer队列中某个block 对应的scn 。

如果在dbwr写dirty buffer时候,发生掉电,则恢复过程肯定是:首先从控制文件中找到,上次检查点发生后最后成功写入那个block块对应的Scn往后进行恢复。也就是ckpt进程在掉电前那最后一个三秒钟轮回,向控制文件写如的scn为恢复的前界限,往后进行恢复。
检查点是一个数据库事件,它把修改数据从高速缓存写入磁盘,并更新控制文件和数据文件。

检查点分为三类:
    1)局部检查点:单个实例执行数据库所有数据文件的一个检查点操作,属于此实例的全部脏缓存区写入数据文件。
触发命令:svmrgrl>alter system checkpoint local;
这条命令显示的触发一个局部检查点。
    2)全局检查点:所有实例(对应并行数据服务器)执行数据库所有所有数据文件的一个检查点操作,属于此实例的全部脏缓存区写入数据文件。
触发命令svrmgrl>alter system checkpoint global;
这条命令显示的触发一个全局检查点。
    3)文件检查点:所有实例需要执行数据文件集的一个检查点操作,如使用热备份命令alter tablespace USERS begin backup,或表空间脱机命令alter tablespace USERS offline,将执行属于USERS表空间的所有数据文件的一个检查点操作。

检查点处理步骤:
    1)获取实例状态队列:实例状态队列是在实例状态转变时获得,ORACLE获得此队列以保证检查点执行期间,数据库处于打开状态;
    2)获取当前检查点信息:获取检查点记录信息的结构,此结构包括当前检查点时间、活动线程、进行检查点处理的当前线程、日志文件中恢复截止点的地址信息;
    3)缓存区标识:标识所有脏缓存区,当检查点找到一个脏缓存区就将其标识为需进行刷新,标识的脏缓存区由系统进程DBWR进行写操作,将脏缓存区的内容写入数据文件;
    4)脏缓存区刷新:DBWR进程将所有脏缓存区写入磁盘后,设置一标志,标识已完成脏缓存区至磁盘的写入操作。系统进程LGWR与CKPT进程将继续进行检查,直至DBWR进程结束为止;
    5)更新控制文件与数据文件。
注:控制文件与数据文件头包含检查点结构信息。

在两种情况下,文件头中的检查点信息(获取当前检查点信息时)将不做更新:

  1)数据文件不处于热备份方式,此时ORACLE将不知道操作系统将何时读文件头,而备份拷贝在拷贝开始时必须具有检查点SCN;
ORACLE在数据文件头中保留一个检查点的记数器,在正常操作中保证使用数据文件的当前版本,在恢复时防止恢复数据文件的错误版本;即使在热备份方式下,计数器依然是递增的;每个数据文件的检查点计数器,也保留在控制文件相对应数据文件项中。

  2)检查SCN小于文件头中的检查点SCN的时候,这表明由检查点产生的改动已经写到磁盘上,在执行全局检查点的处理过程中,如果一个热备份快速检查点在更新文件头时,则可能发生此种情况。应该注意的是,ORACLE是在实际进行检查点处理的大量工作之前捕获检查SCN的,并且很有可能被一条象热备份命令 alter tablespace USERS begin backup进行快速检查点处理时的命令打断。
ORACLE在进行数据文件更新之前,将验证其数据一致性,当验证完成,即更新数据文件头以反映当前检查点的情况;未经验证的数据文件与写入时出现错误的数据文件都被忽略;如果日志文件被覆盖,则这个文件可能需要进行介质恢复,在这种情况下,ORACLE系统进程DBWR将此数据文件脱机。

  检查点算法描述:
脏缓存区用一个新队列链接,称为检查点队列。对缓存区的每一个改动,都有一个与其相关的重做值。检查点队列包含脏的日志缓存区,这些缓存区按照它们在日志文件中的位置排序,即在检查点队列中,缓存区按照它们的低重做值进行排序。需要注意的是,由于缓存区是依照第一次变脏的次序链接到队列中的,所以,如果在缓存区写出之前对它有另外的改动,链接不能进行相应变更,缓存区一旦被链接到检查点队列,它就停留在此位置,直到将它被写出为止。

ORACLE系统进程DBWR在响应检查点请求时,按照这个队列的低重做值的升序写出缓存区。每个检查点请求指定一个重做值,一旦DBWR写出的缓存区重做值等于或大雨检查点的重做值,检查点处理即完成,并将记录到控制文件与数据文件。
由于检查点队列上的缓存区按照低重做值进行排序,而DBWR也按照低重做值顺序写出检查点缓存区,故可能有多个检查点请求处于活动状态,当DBWR写出缓存区时,检查位于检查点队列前端的缓存区重做值与检查点重做值的一致性,如果重做值小于检查点队列前缓存区的低重做值的所有检查点请求,即可表示处理完成。当存在未完成的活动检查点请求时,DBWR继续写出检查点缓存区。

算法特点:
    1)DBWR能确切的知道为满足检查点请求需要写那些缓存区;
    2)在每次进行检查点写时保证指向完成最早的(具有最低重做值的)检查点;
    3)根据检查点重做值可以区别多个检查点请求,然后按照它们的顺序完成处理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值