【原】关于SCN

作者:david_zhang@sh 【转载时请以超链接形式标明文章】

链接:http://www.cnblogs.com/david-zhang-index/archive/2012/03/22/2411203.html

关于scn1

SCN是什么?

The System Change Number system change number (SCN)是一个非常重要的标记,Oracle使用它来标记数据库在过去时间内的状态和轨迹,Oracle使用SCN来保存所有变化的轨迹。SCN是一个逻辑时钟来记录数据库事件,它非常的重要,并不是只是为了恢复,SCN有点类似于sequence,Oracle在SGA中增加它。当一个事务修改或者插入数据,Oracle首先写入一个新的SCN到回滚段中,log writer进程立刻把提交的记录写入到重做日志中,这条提交的记录将拥有唯一的SCN。事实上,把SCN写入到日志,就意味着一个事务的完成。SCN帮助Oracle决定在一次突然中断或者SHUTDOWN ABORT后,是否需要一个崩溃恢复。每当数据库发生checkpoint,Oracle 写一个START SCN到数据文件头,控制文件维护着每个数据文件的SCN——称为STOP SCN,通常是无穷大,每当实例正常关闭(SHUTDOWN NORMAL or SHUTDOWNIMMEDIATE),Oracle会复制数据文件头START SCN到控制文件的STOP SCN。如果是正常的重启数据库,是不需要恢复的,因为控制文件和数据文件的SCN是吻合的,反之,突然中断系统就没法同步SCN,SCN不匹配,Oracle就认为需要做恢复。另外Oracle还使用数据块的SCN来维护查询的一致性和多版本。

Checkpoint是一个数据库事件,用来同步所有的datafile,controlfile和redo logfile。当发出ckpt时(回顾什么时候oracle会发出ckpt呢),ckpt会将检查点时刻的scn写入到控制文件和数据文件头部,同时会促使dbwr进程将data buffer中的所有的脏数据写入到数据文件中。而dbwr进程工作时又会促使lgwr写log buffer中的日志数据到redo logfile中。所以当发出检查点时CKPT,DBWR和LGWR同时工作,三种文件的scn完全一致,从而能保持完全同步。

一次checkpoint包含以下步骤:

1. 把redo buffers的内容刷到redo log中

2. 在redo log file中留下一个checkpoint记录

3. 把database buffer cache的变更刷新到磁盘

4. 在checkpoint完成后,更新数据文件头和控制文件。

Checkpoint的具体工作包括:

1. 触发DBWn向磁盘写入Dirty data

2. 把checkpoint信息更新到datafile header上

3. 把checkpoint信息更新到control file里

Checkpoint做的事情之一是触发DBWn把buffer cache中的Dirty cache刷新到磁盘,另外就是把最近的系统的SCN更新到datafile header和control file(每一个事务都有一SCN),做第一件事的目的是为了减少由于系统突然宕机而需要的恢复时间,做第二件事实为了保证数据库的一致性。

checkpoint的作用就是 :

1.减少系统崩溃导致的恢复时间

2.保证数据库的一致性

确保定期向磁盘写入内存中发生修改的数据块,以便在系统或数据库失败时不会丢失数据 ,缩短例程恢复所需的时间。只需处理最后一个检查点后面的重做日志条目以启动恢复操作 ,确保提交的所有数据在关闭期间均已写入数据文件 由 CKPT 写入的检查点信息包括检查点位置、系统更改号、重做日志中恢复操作的起始位置以及有关日志的信息等等。

checkpoint触发:

一、log switch

二、data buffer cache达到指定块

三、达到checkpoint指定时间

具体如下:

1.当发生日志组切换的时候,减少crash后的recovery时间

2.当符合 LOG_CHECKPOINT_TIMEOUT,LOG_CHECKPOINT_INTERVAL,fast_start_io_target,fast_start_mttr_target 参数设置的时候    LOG_CHECKPOINT_TIMEOUT 默认1800秒     LOG_CHECKPOINT_INTERVAL 默认 0     fast_start_mttr_target 默认,如果被指定,会覆盖LOG_CHECKPOINT_INTERVAL     fast_start_io_target,10g以后已经抛弃

3.当 ALTER SYSTEM SWITCH LOGFILE,ALTER SYSTEM CHECKPOINT

4.当 alter tablespace XXX begin backup,end backup 5.当 alter tablespace ,datafile offline ;

关于scn2

1、SCN的介绍 Oracle中的SCN有下面几种:

①系统检查点scn(v$database(checkpoint_change#)) 当一个检查点动作完成之后,Oracle就把系统检查点的SCN存储到控制文件中 

select checkpoint_change# from v$database;   

②数据文件检查点scn (v$datafile(checkpoint_change#)) 当一个检查点动作完成之后,Oracle就把每个数据文件的scn单独存放在控制文件中 

select name,checkpoint_change# from v$datafile;   

③数据文件终止scn (v$datafile(last_change#))    

每个数据文件的终止scn都存储在控制文件中。在正常的数据库操作过程中,所有正处于联机读写模式下的数据文件的终止scn都为null      

select name,last_change# from v$datafile;   

④数据文件启动scn (v$datafile_header(checkpoint_change#) Oracle把这个检查点的scn存储在每个数据文件的文件头中,这个值称为启动scn,因为它用于在数据库实例启动时,检查是否需要执行数据库恢复      

select name,checkpoint_change# from v$datafile_header;

2、SCN的工作机制:

①在数据库打开并运行之后,控制文件中的系统检查点scn、控制文件中的数据文件检查点scn和每个数据文件头中的启动scn都是相同的   

②控制文件中的每个数据文件的终止scn都为null   

③NORMAL或IMMEDIATE关闭数据库的过程中,系统会执行一个检查点动作,这时所有数据文件的终止scn都会设置成数据文件头中的那个启动scn的值。   

④在数据库重新启动的时,Oracle将执行两次检查       

  ◆看数据文件头中的ckpt计数器是否与对应控制文件中的ckpt计数器一致。若相等,进行第二次检查       

  ◆比较文件头中的启动scn和对应控制文件中的终止scn进行比较,如果终止scn等于启动scn,则不需要对那个文件进行恢复   

⑤数据库打开之后,存储在控制文件中的数据文件终止scn的值再次被更改为null,这表示数据文件已经打开并能够正常使用了

 注:当ABORT强制关闭数据库时不进行检查点处理,所以终止scn仍然为无穷大。在下次启动期间,发现启动scn和终止scn不同,需要进行线程恢复。

3、SCN的增加

①SCN(System Change Number)只要数据库被修改,就会+1,而不是一定要进行checkpoint,例如DML的发生即使没有提交也会使SCN+1   

注:SCN增加并不代表会在数据文件头中表现出来,而是需要等到checkpoint执行后才写入(当然可能已经增加了很多)   

②如果一个DML导致产生事务,则会产生一个SCN。这个意思是说如果一个事务包含多个dml,则只有第一个初始产生事务的dml产生scn,提交的时候又是一个scn,如果一个事务只有一个dml,拿看起来就是dml产生一个scn,提交或者回滚产生一个scn。   

③Oracle 10g内部的SCN会默认不管有没有动作,每隔3s自动增加一次。其他需要增加的情况则再加。   

④只有ckpt进程才会修改文件头中的checkpoint计数器和SCN,DBWR只会修改数据块,即ckpt通知dbwr写数据文件,写完之后ckpt更新控制文件和数据文件头。此时若DBWR发现数据块的log block还没有被写入日志文件,则在dbwr写块之前通知llgwr把log buffer中的日志写入log文件。   

注:总结一下,日志切换必定出发ckpt,但ckpt不一定会出发llgwr,但是一定会触发dbwr

4、其他的SCN

①日志文件头中包含了Low scn、Next scn,表示给日志文件包含有从Low scn到Next scn的redo record   

注:当系统运行时,日志文件的Next scn同样为无穷大。而且需要注意:在恢复时不是用日志文件中的Low scn和Next scn来选择恢复的日志文件,而是通过数据文件头中的信息。   

 ②数据块中的SCN data block里面的SCN是当block被更改的时候的SCN,而数据文件有那么多block,自然不同的block有不同的SCN,block中存在block SCN和ITL中commit SCN。block SCN又在块头和块位都有,若不一致意味着block损坏。而ITL中的commit SCN则跟consistent gets and delay block cleanout有关。   

③v$database中的checkpoint_change#和dbms_flashback.get_system_change_number不同。前者是作为数据库的最后一次checkpoint是的SCN,而后者是系统的最新SCN,所以一般后者都会比前者大,而当刚做完checkpoint时两者会差不多。   

 ④当begin backup命令发出后,相关数据文件的checkpoint scn被冻结(以及状态标志被改变),其他一切照旧。例如:日志切换时checkpoint count正常递增/检查点照常写文件,自然文件中的数据块内的各种scn也照常递增。

关于scn3

SCN(System Chang Number)作为oracle中的一个重要机制,在数据恢复、Data Guard、Streams复制、RAC节点间的同步等各个功能中起着重要作用。 理解SCN的运作机制,可以帮助你更加深入地了解上述功能。 在理解SCN之前,我们先看下oracle事务中的数据变化是如何写入数据文件的:

1、 事务开始;

2、 在buffer cache中找到需要的数据块,如果没有找到,则从数据文件中载入buffer cache中;

3、 事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;

4、 事务提交,LGWR进程将log buffer中的“脏数据”写入redo log file中;

5、 当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWn进程则负责将Buffer Cache中的脏数据写入到数据文件中。

经过上述5个步骤,事务中的数据变化最终被写入到数据文件中。但是,一旦在上述中间环节时,数据库意外宕机了,在重新启动时如何知道哪些数据已经写入数据文件、 哪些没有写呢(同样,在DG、streams中也存在类似疑问:redo log中哪些是上一次同步已经复制过的数据、哪些没有)? SCN机制就能比较完善的解决上述问题。 SCN是一个数字,确切的说是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了Oracle知道哪些应该被恢复、哪些应该被复制。

总共有4中SCN:

系统检查点(System Checkpoint)SCN、数据文件检查点(Datafile Checkpoint)SCN、结束SCN(Stop SCN)、开始SCN(Start SCN)。其中前面3种SCN存在于控制文件中,最后一种则存在于数据文件的文件头中。 在控制文件中,System Checkpoint SCN是针对整个数据库全局的,因而之存在一个,而Datafile Checkpoint SCN和Stop SCN是针对每个数据文件的,因而一个数据文件 就对应在控制文件中存在一份Datafile Checkpoint SCN和Stop SCN。在数据库正常运行期间,Stop SCN(通过视图v$datafile的字段last_change#可以查询) 是一个无穷大的数字或者说是NULL。 在一个事务提交后(上述第四个步骤),会在redo log中存在一条redo记录,同时,系统为其提供一个最新的SCN(通过函数dbms_flashback.get_system_change_number可以 知道当前的最新SCN),记录在该条记录中。如果该条记录是在redo log被清空(日志满做切换时或发生checkpoint时,所有变化日志已经被写入数据文件中), 则其SCN被记录为redo log的low SCN。以后在日志再次被清空前写入的redo记录中SCN则成为Next SCN。 当日志切换或发生checkpoint(上述第五个步骤)时,从Low SCN到Next SCN之间的所有redo记录的数据就被DBWn进程写入数据文件中, 而CKPT进程则将所有数据文件(无论redo log中的数据是否影响到该数据文件)的文件头上记录的Start SCN(通过视图v$datafile_header的字段checkpoint_change#可以查询) 更新为Next SCN,同时将控制文件中的System Checkpoint SCN(通过视图v$database的字段checkpoint_change#可以查询)、每个数据文件对应的Datafile Checkpoint (通过视图v$datafile的字段checkpoint_change#可以查询)也更新为Next SCN。但是,如果该数据文件所在的表空间被设置为read-only时,数据文件的Start SCN和控制文件中Datafile Checkpoint SCN都不会被更新。 那系统是如何产生一个最新的SCN的?实际上,这个数字是由当时的timestamp转换过来的。每当需要产生一个最新的SCN到redo记录时,系统获取当时的timestamp, 将其转换为数字作为SCN。我们可以通过函数SCN_TO_TIMESTAMP(10g以后)将其转换回timestamp:

SQL> select dbms_flashback.get_system_change_number, SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual;

GET_SYSTEM_CHANGE_NUMBER    SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER)

------------------------  ---------------------------------------------------------------------------

2877076756    17-AUG-07 02.15.26.000000000 PM

也可以用函数timestamp_to_scn将一个timestamp转换为SCN:

SQL> select timestamp_to_scn(SYSTIMESTAMP) as scn from dual;

SCN

----------

2877078439

最后,SCN除了作为反映事务数据变化并保持同步外,它还起到系统的“心跳”作用——每隔3秒左右系统会刷新一次系统SCN。 下面,在简单介绍一下SCN如何在数据库恢复中起作用。 数据库在正常关闭(shutdown immediate/normal)时,会先做一次checkpoint,将log file中的数据写入数据文件中,将控制文件、数据文件中的SCN(包括控制文件中的Stop SCN)都更新为最新的SCN。 数据库异常/意外关闭不会或者只更新部分Stop SCN。 当数据库启动时,Oracle先检查控制文件中的每个Datafile Checkpoint SCN和数据文件中的Start SCN是否相同,再检查每个Datafile Checkpoint SCN和Stop SCN是否相同。 如果发现有不同,就从Redo Log中找到丢失的SCN,重新写入数据文件中进行恢复。具体的数据恢复过程这里就不再赘述。 SCN作为Oracle中的一个重要机制,在多个重要功能中起着“控制器”的作用。了解SCN的产生和实现方式,帮助DBA理解和处理恢复、DG、Streams复制的问题。 最后提一句,利用SCN机制,在Oracle10g、11g中又增加了一些很实用的功能——数据库闪回、数据库负载重现等。

系统检查点scn(v$database(checkpoint_change#))

数据文件检查点(v$datafile(checkpoint_change#))

数据文件终止scn(v$datafile(last_change#))

数据文件中存放的检查点

启动scn (v$datafile_header(checkpoint_change#)

1、系统检查点scn

当一个检查点动作完成之后,Oracle就把系统检查点的SCN存储到控制文件中。

select checkpoint_change# from v$database

2、数据文件检查点scn

当一个检查点动作完成之后,Oracle就把每个数据文件的scn单独存放在控制文件

中。

select name,checkpoint_change# from v$datafile

3、启动scn

Oracle把这个检查点的scn存储在每个数据文件的文件头中,这个值称为启动scn,

因为它用于在数据库实例启动时,检查是否需要执行数据库恢复。

select name,checkpoint_change# from v$datafile_header

4、终止scn

每个数据文件的终止scn都存储在控制文件中。

select name,last_change# from v$datafile

在正常的数据库操作过程中,所有正处于联机读写模式下的数据文件的终止scn都为null.

5、在数据库运行期间的scn值

在数据库打开并运行之后,控制文件中的系统检查点、控制文件中的数据文件检查点scn

和每个数据文件头中的启动scn都是相同的。控制文件中的每个数据文件的终止scn都为null.

在安全关闭数据库的过程中,系统会执行一个检查点动作,这时所有数据文件的终止scn

都会设置成数据文件头中的那个启动scn的值。在数据库重新启动的时候,

Oracle将文件头中的那个启动scn与数据库文件检查点scn进行比较,

如果这两个值相互匹配,oracle接下来还要比较数据文件头中的启动scn和控制文件

中数据文件的终止scn。如果这两个值也一致,就意味着所有数据块多已经提交,所有

对数据库的修改都没有在关闭数据库的过程中丢失,因此这次启动数据库的过程

也不需要任何恢复操作,此时数据库就可以打开了。当所有的数据库都打开之后,

存储在控制文件中的数据文件终止scn的值再次被更改为null,

这表示数据文件已经打开并能够正常使用了

系统检查点scn(v$database(checkpoint_change#))

数据文件检查点(v$datafile(checkpoint_change#))

数据文件终止scn(v$datafile(last_change#))

数据文件中存放的检查点

启动scn (v$datafile_header(checkpoint_change#)

1、系统检查点scn

当一个检查点动作完成之后,Oracle就把系统检查点的SCN存储到控制文件中。

select checkpoint_change# from v$database

2、数据文件检查点scn

当一个检查点动作完成之后,Oracle就把每个数据文件的scn单独存放在控制文件

中。

select name,checkpoint_change# from v$datafile

3、启动scn

Oracle把这个检查点的scn存储在每个数据文件的文件头中,这个值称为启动scn,

因为它用于在数据库实例启动时,检查是否需要执行数据库恢复。

select name,checkpoint_change# from v$datafile_header

4、终止scn

每个数据文件的终止scn都存储在控制文件中。

select name,last_change# from v$datafile

在正常的数据库操作过程中,所有正处于联机读写模式下的数据文件的终止scn都为null.

5、在数据库运行期间的scn值

在数据库打开并运行之后,控制文件中的系统检查点、控制文件中的数据文件检查点scn

和每个数据文件头中的启动scn都是相同的。控制文件中的每个数据文件的终止scn都为null.

在安全关闭数据库的过程中,系统会执行一个检查点动作,这时所有数据文件的终止scn

都会设置成数据文件头中的那个启动scn的值。在数据库重新启动的时候,

Oracle将文件头中的那个启动scn与数据库文件检查点scn进行比较,

如果这两个值相互匹配,oracle接下来还要比较数据文件头中的启动scn和控制文件

中数据文件的终止scn。如果这两个值也一致,就意味着所有数据块多已经提交,所有

对数据库的修改都没有在关闭数据库的过程中丢失,因此这次启动数据库的过程

也不需要任何恢复操作,此时数据库就可以打开了。当所有的数据库都打开之后,

存储在控制文件中的数据文件终止scn的值再次被更改为null,

这表示数据文件已经打开并能够正常使用了。

示例:

select dbid,checkpoint_change# from v$database;

select name,checkpoint_change#,last_change# from v$datafile;

select name,checkpoint_change# from v$datafile_header;

select b.name,a.checkpoint_change# sys_snc,c.checkpoint_change# start_scn,b.last_change# end_scn from v$database a,v$datafile b,v$datafile_header c where b.file#=c.file#;

点击按提示下载:关于scn.7z

posted @ 2012-03-22 10:35  david_zhang@sh  阅读(529)  评论(0编辑  收藏  举报