初学checkpoint and scn


关于备份恢复这一块,经常要使用SCN来分析问题,SCN跟CHECKPOINT好像又有着一些联系.当然在网上已经有很多前辈做过总结,在这我参考了许多前辈的资料,自己就scn和checkpiont也做一个小小的总结,希望这样能加深自己的印象,也跟大家分享,如果有错误,望大家不吝指教。
SCN和Checkpoint的确是一个难点,但他们对oracle数据库有着非常重要的意义。下面我会对scn和checkpoint分别做介绍,然后再看看他们之间有没有一些联系。
先说SCN
SCN的意义:SCN是系统改变号(SYSTEM CHANGE NUMBER),是一个数值,它其实相当于一个时间,ORACLE数据库用它来记录数据库的变化,SCN之间可以进行比较以得出对数据库的各种操作的先后。
SCN的种类:主要常见的有4种
1.System Checkpoint SCN 系统检测点SCN 
查看:select checkpoint_change# from v$database;
2.Datafile Checkpoint SCN 数据文件检查点SCN
查看:select name,checkpoint_change# from v$datafile;
3.Start SCN 开始SCN
查看:select name,checkpoint_change# from v$datafile_header; 
4.Stop SCN 结束SCN
查看:select name,last_change# from v$datafile;
那么这常见的4种SCN是存放在哪,有什么用呢?
存放位置:系统检测点SCN 数据文件检查点SCN 结束SCN 是存放在控制文件中的,而开始SCN存放在数据文件的头部
注意:每个数据文件头部都有开始SCN,而ORACLE中有多少个数据文件,在控制文件中就有对应有多少个数据文件检查点SCN和结束SCN而系统检查点SCN只有一个
SCN的作用:
在说作用之前,应该先讲他们的初始值。
数据库在正常运行时,系统检测点SCN 数据文件检查点SCN以及开始SCN是一样的,而结束SCN为空。这是数据库正常运行的状态
那么从数据库启动开始说起。数据库开启分(nomount mount open)3个阶段。
在数据库要打开时(open),ORACLE会检查所有数据文件头部的开始SCN,拿它和控制文件中的数据文件检查点SCN比较(我们说过SCN是一个数值)。如果相同,它就继续看控制文件中的Stop SCN,如果Stop SCN和Start SCN相同,那么数据库就能正常打开。如果Stop SCN和Start SCN不同,则数据库需要做实例恢复。如果在前面比较控制文件中的数据文件检查点SCN和数据文件头部的SCN时就出现了不同,那么数据库就会做介质恢复。
之所以会这样,是因为【数据库正常运行时System Checkpoint SCN=Datafile Checkpoint SCN=Start SCN,Stop=null】这我们前面讲过
如果数据库正常关闭:shutdown normal/immediate/transactional ,系统会发生完全检查点(这我们在下面再讲),把控制文件中的Stop SCN改为数据文件头部的Start SCN再关闭数据库。也就是说正常关闭数据库的话,我们重启数据库检查这4个SCN他们都是一样的,能正常打开。
如果数据库非正常关闭,shutdown abort,掉电等,ORACLE没来得及将Stop SCN置为和Start SCN一样,那么在重新打开数据库是,检查这4个SCN,会发现Stop SCN 的置为空
ORACLE就知道数据库非正常关闭,需要做实例奔溃恢复。
还有一种情况,就是我们数据库是正常关闭,但是我们由于一个数据文件丢了,我们用一个备份的数据文件来恢复到原来位置,但是它是备份的,文件头部的Start SCN 非常有可能是小于现在数据库使用的控制文件中的各个SCN值,那么数据库就会提醒我们做介质恢复。
上面这些就是数据库利用SCN值来判断是否需要做恢复,做哪种恢复的原理。需要注意的是,数据库是先判断Start SCN值是否与现有的其他SCN相等,再判断Stop SCN。也就是说,如果数据库既需介质恢复,又需实例奔溃恢复时,是先做介质恢复的。
SCN是什么时候变化的:在上面说过,数据库正常关闭时会发生完全检查点,将Stop SCN置为和Start SCN一样。这时Stop SCN改变。那么其他的3个SCN值会改变吗?他们什么时候改变呢?
其实在数据库中还有2种常用的SCN
1.日志文件头部带有low SCN和 next SCN
(每条日志记录都有一个SCN号)
日志文件的头部中的low SCN 和 next SCN是用来做数据库恢复用的。low SCN代表该日志文件最早一条日志所对应的SCN,next SCN代表该日志文件最后一条日志所对应的SCN。
也就是说该日志文件是可以用来恢复 SCN值在LOW SCN 到NEXT SCN之间的事物和数据改变的。

日志文件有三种状态,inactive,active,current
inactive代表这个日志文件里面没数据或者可以被覆盖,active代表这个日志文件里面有数据,而且对应的在SGA里面的buffer cache还没有写到磁盘。也就是说该日志文件不能被覆盖,因为对应的缓冲数据还没写到磁盘,如果系统奔溃,到时还需要使用到该日志文件进行恢复,所以不能覆盖。current代表该日志文件正在被使用也不能被覆盖。
2.系统当前的current SCN
系统当前的SCN号不一定是和文件头部和控制文件中的那些SCN号相等的,它是在不断改变的。它改变的触发条件有很多,这里就不具体说了。可以使用查看 select current_scn from v$database;

我们这里是要讲上面4种SCN上面时候变化的(当然Stop SCN我们已经知道什么时候变化了),那么还有3种(Start SCN,System Checkpoint SCN,Datafile Checkpoint SCN)它们在数据库正常运行期间是要保持相同的,所以改变时它们也是同步改变的。(Start SCN,System Checkpoint SCN,Datafile Checkpoint SCN),他们是与最近一次执行完全检查点时的那个SCN值相等的,至于什么时候执行完全检查点,我们下面会讲。而且这个SCN值是大于等于当前最老的active或current日志所对应的First_change#.意思就是如果控制文件和数据文件要做恢复时,是要使用控制文件和数据文件中三个SCN值所对应的大于等于first scn的日志文件开始恢复。
比如:
在数据库正常运行期间
--查看系统当前的System Checkpoint SCN


--查看当前日志的情况

--可以看出,System Checkpoint SCN等于 current日志的first_change#
--现在切换日志2次(会发生完全检查点),重新查看日志文件和System Checkpoint SCN

发现System Checkpoint SCN等于 active日志序列号为11的日志的first_change#,说明此时DBWR还没将脏块写到数据文件,这些日志还不能被覆盖,到时奔溃恢复时,我们需要根据System Checkpoint SCN 找到对应的日志文件,再根据lrba(下面检查点队列会讲)找到日志记录开始恢复。
让我们不做任何操作等待一段时间,这段时间内,DBWR会触发(每隔三秒或其他触发条件),把脏数据写到磁盘,对应的日志文件也会从active变成inactive。那么我们再来查一下日志文件和System Checkpoint SCN

不出所料,原来2个ACTIVE日志文件变成了inactive状态。而System Checkpoint SCN记录的是大于等于最早的active或current日志文件中的low SCN(FIRST_CHANGE#)。
那么此时它等于current日志的first_change#.Start SCN,System Checkpoint SCN,Datafile Checkpoint SCN)。
注意:最早的active日志中的最早指的是sequecce#值最小的。切换日志之后,并不会立即更新SCN,要等DBWR写完需要写的脏块后,完全检查点才完成并将SCN更新到控制文件和数据文件头部。

如:我设置log_checkpoints_to_alert参数为TRUE,这么数据库发生的检查点信息都会记录到警告文件中。我执行切换日志操作(alter system switch logfile),查看警告文件,里面写到

在19点47分时开始切换日志到检查点位置 指定(RBA [0x15.2.10] SCN:1497417),此时去查控制文件的各个SCN它还是保持和之前的一样。但是在19:52分时,完全检查点完成,然后记录了RBA和SCN到控制文件。

这时再去查控制文件中的SCN就等于1497417.


相信大家都注意到了,我们这3个SCN值是一般情况是一样的,Start SCN=System Checkpoint SCN=Datafile Checkpoint SCN
Start SCN用于判断数据文件是否是旧的,用于判断是否进行数据文件介质恢复。而System Checkpoint SCN和Datafile Checkpoint SCN是否重复呢?
使用一个可以吗?答案是不可以
我查了一些资料,下面是解释:
1.对只读表空间,其数据文件的Datafile Checkpoint SCN、Start SCN和END SCN号均相
同。这三个 SCN在表空间处于只读期间都将被冻结。
2.如果控制文件不是当前的控制文件,则System checkpoint会小于Start SCN或END SCN
号。
记录这些SCN号,可以区分控制文件是否是当前的控制文件。

终于讲完scn了,可能讲的不是很清楚!!!

下面是检查点。
什么是检查点队列(Checkpoint queue)?
检查点队列是存在于SGA中,它是一个链表,链接着BUFFER CACHE中的脏块,每个数据块上都有一个buffer header,在这个头部里面有一个ckptq项,它可以记录检查点队列的上一个块地址和下一个块地址
而检查点队列是按照一个脏块第一次被脏的时间点链起来的。
例如:现在有4个脏块,d1,d2,d3,d4,他们被脏的时刻分别为
d1         7:30:14
d2         7:30:50 
d3         7:31:01
d4         7:31:30
d1         7:32:00
d3         7:32:01
我们假设在这个时间段内DBWR并没有将这4个脏块写到磁盘,(DBWR会因很多原因触发),那么我们看到在7:32:00后时刻,d1和d3块又被脏了一次,但是数据库里的检查点队列上面的排列顺序任然是 d1->d2->d3->d4,这就是检查点队列。
接下来讲检查点,检查点有2种
1.完全检查点
在上面讲到SCN时我们已经说过,完全检查点发生在数据库正常关闭时,在数据库正常运行过程中,完全检查点几乎不发生。在发生完全检查点时,ckpt(检查点进程)会触发DBWR把数据库中发生检查点之前的SCN对应的脏数据写到磁盘。然后会用发生检查点时的SCN更新控制文件中的系统检查点SCN,数据文件检查点SCN和数据文件头部开始SCN。而这里有个心跳的概念,每隔三秒,CKPT会去查看dbwr写到什么位置了,然后把对应的块的lrba地址写到控制文件。

注意:如果对应的是由于正常关机引起的完全检查点还会用每个数据文件头部的Start SCN 更新控制文件中的Stop SCN。

完全检查点触发条件:

1.数据库正常关机。
2.alter tablespace tablespace_name offline;将表空间脱机

3.Alter system switch logfile;

4.alter system checkpoint;手动执行完全检查点

5.相关参数的设置LOG_CHECKPOINT_INTERVAL, LOG_CHECKPOINT_TIMEOUT ,FAST_START_IO_TARGET 

注意:alter database datafile ‘dir’ offline;不会发生检查点 
2.增量检查点
下面是参考Dave博客http://blog.csdn.net/tianlesoftware/article/details/6700085的关于增量检查点的英文文档
 Incremental Checkpoint
? Writes the contents of “some” dirty buffers to the database from CKPT-Q
? Block images written in SCN order
? Checkpoint RBA updated in SGA
? Statistics updated:
– DBWR checkpoint buffers written
? Controlfile is updated every 3 seconds byCKPT
– Checkpoint progress record

Definition of “Some”
? Every 3 seconds CKPT calculates thecheckpoint
target RBA based on:
– The most current RBA
– log_checkpoint_timeout
– log_checkpoint_interval
– fast_start_mttr_target
– fast_start_io_target
– 90% of the size of the smallest onlineredo log file
? All buffers dirtied prior to the timecorresponding to the target RBA are written to the database

大体意思是: CKPT进程平时会检查(ckpt-Q)检查点队列是否过长,会触发DBWR写“一部分”脏块到磁盘,DBWR是按照(ckpt-Q)检查点队列的先后写的,增量检查点发生时,会往控制文件中写入当前检查点队列的第一块的lrba地址,(lrba地址指的是该块第一次被脏所对应的日志地址,这里不详细讲,大家可以参考网上很多前辈的文章),然后还有个心跳的概念。
上面讲得有些乱,下面总结一下到底上面是增量检查点,它到底做了些什么。

当触发增量检查点时,
CKPT进程会根据一套方法(具体是根据一些参数的设置SCN,I/O繁忙度),去检查检查点队列是否过长,计算出一个target RBA,然后CKPT会通知DBWR“你去将我检查点队列上的lrba地址等于target RBA的所对应的脏块之前的块数据写到磁盘),然后DBWR就去写数据了。那么此时CKPT的第一个任务就结束了,注意它不会去等待DBWR去做完它给的任务,到此它的第一个任务就完成了。

那么DBWR在写数据了,CKPT怎样知道他写完了没,或者说写到哪个块了呢?原来,有一个心跳的概念,即每隔三秒钟,CKPT会去检查一次DBWR写到哪个位置了,同时还把此时刚写完的dirty buffer对应的lrba记录到控制文件,这个就是检查点位置这就是CKPT的第二个任务了。

那么这2个任务所组合起来完成的任务就是增量检查点做的任务。当CKPT触发DBWR写数据,然后CKPT每3秒将检查点位置更新到控制文件中,就完成了一个增量检查点。(注意增量检查点并不更新控制文件和数据文件头部的SCN)
增量检查点触发条件:

1. 在联机热备份数据文件前,要求该数据文件中被修改的块从DB_Buffer 写入数据文件中。所以,发出这样的命令:

ALTER TABLESPACE tablespace_name BIGEN BACKUP & end backup; 也将触发和该表空间的数据文件有关的局部检查点;

2.alter tablespace name read only;

3.Alter tablespace name offline normal;(与alter tablespace name offline发生完全检查点做区分)
还得讲讲检查点的意义:
很简单,系统会由于我们的各种操作,脱机表空间,数据文件手动执行检查点还有初始化参数等原因触发检查点,其意义
将SGA中脏块写到磁盘,不要让太多脏块堆积在SGA中,最终目的还是保护数据库的一致性和完整性。想一下,如果数据库掉电,宕机了
我们重启时一定要做恢复,如果有大量的脏块本来在SGA中,现在丢了,是不是恢复起来速度很慢?那么要做恢复,需要日志,那么数据库怎么知道我用
哪些日志做恢复,做什么类型的恢复呢?这就是检查点发生时往控制文件数据文件头部写的检查点scn和检查点位置(lrba)起作用了。


数据库在需要做恢复时的步骤
上面讲过SCN做恢复时,系统采取的措施和步骤
现在是结合检查点和SCN,系统真正做恢复时是这样进行操作的。
1.重启数据库,检查各个文件的SCN值(开始SCN,结束SCN,系统检查点SCN,数据文件检查点SCN),确定要做介质恢复还是实例奔溃恢复
2.如果确定要做恢复,根据检查点SCN值找到对应的日志文件,然后再根据检查点位置(lrba)找到该日志文件的对应记录,开始跑日志,做恢复。

最后做一个实验,目的是看看SCN和检查点之间的联系,即我们手动执行检查点后,数据文件头部和控制文件中的SCN应该会和我们执行检查点时的SCN一样。
数据库在正常运行期间,DBWR往数据库磁盘写数据不一定都是因为发生检查点,CKPT触发DBWR写数据,即既有非检查点,又有检查点
现在我们查看系统当前的控制文件中的各个SCN,还有数据文件头的Start SCN
这里我们只查System Checkpoint SCN,其他的都和它一样,当然Stop SCN为空

--查看日志文件

大家看这System Checkpoint SCN和active日志对应的SCN不同(大于)。的确,因为我在查看System Checkpoint SCN之前手动执行了检查点,所以System Checkpoint SCN记录的是我当时执行检查点时的SCN。在数据库正常运行期间,有时会自动发生检查点,有时是人为操作导致检查点发生,那么这时控制文件和数据文件头部的SCN就不一定等于最早的active或current日志的low scn了。

--我们再次手动执行检查点,再查看当前scn

查看控制文件中的系统检查点SCN

没错,1459985正是我们执行检查点时的SCN。
初学oracle,多以总结为主,如有遗漏错误,希望指正。



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29227735/viewspace-1063864/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29227735/viewspace-1063864/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值