checkpoint与SCN
时间:2010-11-22 来源:orchidwang
checkpoint
很多人都把checkpoint的概念给复杂化了,其实checkpoint这个数据库概念引入的真正意义就是用来减少数据库恢复所花的时间(instance recovery),那么checkpoint是由谁来做的呢?我们都知道数据库中有个CKPT进程,这个是个可选进程,但是真正执行检查点的任务并不是由CKPT来完成的,而是CKPT在更新控制文件和数据文件头的有关信息后,通知DBWn进程,产生一个检查点,在产生检查点的时候,DBWn进程会将buffer cache中的脏数据(当前online redo log对应的脏数据),写入我们的数据文件当中。那么这个时候如果数据库此时崩溃(比如我们做个shutdown abort),那么在进行实例恢复的时候就可以不需要当前online redo log的内容了,会很快就做完。因此ckpt进程只是个辅助进程,他的任务更多的是用来在系统做checkpoint的时候更新控制文件和数据文件头中的信息。其实在oracle 8i的时候呢,ckpt的任务一般都是由lgwr进程来完成,到了8i以后,随着CKPT进程的引入,lgwr的工作负担就减轻了很多(commit的速度加快了)
那么如何来产生检查点呢?
有三种方法,可以通过
1.alter system checkpoint
2.alter system switch logfile
3.DBWn进程写出脏块
SCN
SCN是系统改变号(system change number)的缩写,在Oracle中可理解为一个内部同步时钟,我们可以通过dbms_flashback包来查询当前系统的改变号:
select dbms_flashback.get_system_change_number from dual;
SCN主要用来标识对数据库所做的所有改变,它只能增加,不能减少,除非重建数据库,否则数据库中的SCN永远不会归0。一般来说SCN的前进触发是由commit来进行的,除了这些据我观察每隔3秒种系统也都会刷新一次SCN.
需要注意的是:
1.在发生checkpoint时,CKPT将数据库当前的SCN更新入数据库文件头和控制文件当中,同时DBWn进程将buffer cache中的脏数据块(dirty block)写到数据文件当中(这个脏数据也一定是当前online redo log保护的那一部分)。
2.同时CKPT进程还会在控制文件当中记录(redo block address)RBA,这个地址用来标志恢复的时候需要从日志中的那个位置开始。
在Oracle数据库中和checkpoint相关的SCN总共有4个,下面分别介绍这四个SCN.
1.System checkpoint SCN (存在于控制文件)
在系统执行checkpoint后,Oracle会更新当前控制文件中的System checkpoint SCN。
我们可以通过
select checkpoint_change# from v$database;
来查看.
2.Datafile checkpoint SCN (存在于控制文件)
在控制文件中记录了Oracle中各个数据库文件的位置和信息,其中也包括了Datafile checkpoint SCN,因此在执行checkpoint的时候,Oracle还会去更新控制文件中所记录的各个数据文件的datafile checkpoint SCN.
我们可以通过
select checkpoint_change# from v$datafile;
来查看。
3.Start SCN (存在于各个数据文件头)
在执行checkpoint时,Oracle会更新磁盘上数据文件头的Start SCN(注意绝对不会是控制文件中),这个SCN是用于检查数据库启动过程中是否需要做media recovery(介质恢复)。
我们可以通过
select checkpoint_change# from v$datafile_header;
来查看。
4.End SCN(存在于控制文件)
End SCN也是记录在控制文件中,控制文件中所记录的每一个数据文件头都有一个对应的End SCN,这个End SCN一定是存在于控制文件中。这个SCN主要是用来验证数据库启动过程中是否需要做instance recovery。我们可以通过
select name,last_change# from v$datafile;
来查看。
在数据库正常运行的情况下,对于read/write的online 数据文件这个SCN号为#FFFFFF(NULL).
下面来聊一聊SCN号与数据库的启动。
1.在数据库的启动过程中,当System Checkpoint SCN=Datafile Checkpoint SCN=Start SCN的时候,Oracle数据库是可以正常启动的,而不需要做任何的media recovery。而如果三者当中有一个不同的话,则需要做media recovery。
2.那什么时候需要做instance recovery呢?其实在正常open数据库的时候,oracle会将记录在控制文件中的每一个数据文件头的End SCN都设置为#FFFFFF(NULL),那么如果数据库进行了正常关闭比如(shutdown or shutdown immediate)这个时候,系统会执行一个检查点,这个检查点会将控制文件中记录的各个数据文件头的End SCN更新为当前online数据文件的各个数据文件头的Start SCN,也就是End SCN=Start SCN,如果再次启动数据库的时候发现二者相等,则直接打开数据库,并再次将End SCN设置为#FFFFFF(NULL),那么如果数据库是异常关闭,那么checkpoint就不会执行,因此再次打开数据库的时候End SCN<>Start SCN这个时候就需要做实例恢复。
说了那么多更新SCN操作什么的,这个更新操作到底是由谁做的呢?其实刚才已经说过了,就是我们的CKPT进程,他不仅仅会更新SCN,而且还会通知DBWn做他的事情。
再说一下System Checkpoint SCN和Datafile Checkpoint SCN,这两个SCN都是记录在控制文件当中的。但是这两个SCN有什么作用呢?
1.对只读表空间,其数据文件的Datafile Checkpoint SCN、Start SCN和END SCN号均相同。这三个SCN在表空间处于只读期间都将被冻结。
2.如果控制文件不是当前的控制文件(其实就是说,相比当前redo log的SCN来讲,控制文件已经过时了),则System checkpoint SCN会小于Start SCN(Start SCN是来自实际的数据文件头,有比较依据)。记录这些SCN号,可以区分控制文件是否是当前的控制文件。当有一个Start SCN(从当前各个online数据文件中获得)号超过了System Checkpoit SCN号时,则说明控制文件不是当前的控制文件,因此在做recovery时需要采用using backup controlfile。这是为什么需要记录SystemCheckpoint SCN的原因之一。