SCN(system change number)是当Oracle数据库更新后,由DBMS自动维护去累积递增的一个数字。Oracle数据库中一共有4种SCN:
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.
其中前面三个scn被存在控制文件中,开始scn被存储在数据文件中。在控制文件中,系统检查点scn是针对整个数据库的,故只存在一个;而数据文件检查点和结束scn是针对每个数据文件的,因而针对每个数据文件,在控制文件中就应该相应的存在一粉数据文件检查点scn和结束scn。在数据库正常运行期间,stop scn是个无穷大的数字或者null。
数据库运行时的SCN
我们先看下oracle事务中的数据变化是如何写入数据文件的:
1、 事务开始;
2、 在buffer cache中找到需要的数据块,如果没有找到,则从数据文件中载入buffer cache中;
3、 事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;
4、 事务提交,LGWR进程将log buffer中的“脏数据”写入redo log file中;
5、 当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWr进程则负责将Buffer Cache中的脏数据写入到数据文件中。
Redo log中的high scn和low scn
Oracle的Redo log会顺序纪录数据库的各个变化。一组redo log文件写满后,会自动切换到下一组redo log文件。则上一组redo log的high scn就是下一组redo log的low scn。在current log中high scn为无穷大。
可通过查询v$log_history查看 low scn和 high scn。
SQL> select recid,sequence#,first_change#,next_change# from v$log_history ;
RECID SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
心跳
Oracle通过CKPT进程每3秒将Heartbeat写入控制文件,以减少故障时的恢复时间
在Oracle内部,SCN分为两部分存储,分别称之为scn wrap和scn base。实际上SCN长度为48位,即它其实就是一个48位的整数。
每隔5 分钟,系统产生一次系统时间标记与scn 的匹配并存入SYS.SMON_SCN_TIME 表(由SMON 进程来进行Update操作),该表中记录了最近1440个系统时间标记与scn 的匹配记录,由于该表只维护了最近的1440 条记录,即最近5 天内的记录。
CHECKPOINT 和 SCN 的关连
checkpoint发生的目的就是要把储存在buffer内的已提交的事务写回disk,否则一旦发生crash,需要进行recovery时,你就必须花很多的时间从redo log file内最后的SCN交易开始进行recovery,这样在商业应用上是很浪费时间和没有效率的。
重点在于当commit一个事务时,只会立刻将redo buffer写入redo log file内,但是并不会马上将该update后的block(dirty block)同步写回disk datafile中,这是为了减少过多disk IO的考虑,所以采取batch的方式写入。
When a checkpoint occurs, Oracle must update the headers of all datafiles to record the details of the checkpoint. This is done by the CKPT process. The CKPT process does not write blocks to disk; DBWn always performs that work.
在shutdown normal or shutdown immediate下,也就是所谓的clean shutdown,checkpoint也会自动触发,并且把SCN纪录写回。
当发生checkpoint时,会把SCN写到四个地方去。
三个地方于control file内,一个在datafile header。
Control file三个地方为
1.System checkpoint SCN ===========> (SYSTEM CHECKPOINT SCN in control file)
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
——————–
292767
2.Datafile checkpoint SCN ===============> (DATAFILE CHECKPOINT SCN in control file)
SQL> select name,checkpoint_change#
from v$datafile where name like ‘%users01%’;
NAME CHECKPOINT_CHANGE#
———————————– ——————–
/u02/oradata/OMFD1/users01.dbf 292767
3.Stop SCN ======================> (STOP SCN in control file)
SQL> select name,last_change#
from v$datafile where name like ‘%users01%’;
NAME LAST_CHANGE#
———————————– ————
/u02/oradata/OMFD1/users01.dbf
正常datafile在read-write mode下 last_change#一定是NULL
另外一个地方在datafile header内
4.Start SCN ================================> (DATAFILE HEADER)
SQL> select name,checkpoint_change#
from v$datafile_header where name like ‘%users01%’;
NAME CHECKPOINT_CHANGE#
———————————– ——————–
/u02/oradata/OMFD1/users01.dbf 292767
相关问题
1 为什么储存在CONTROL FILE中要分为两个地方(SYSTEM CHECKPOINT SCN,DATAFILE CHECKPOINT SCN) ?
当你把一个tbs设为read-only时,他的SCN会冻结停止,此时DATAFILE CHECKPOINT SCN是不会再递增改变的, 但是整体的SYSTEM CHECKPOINT SCN却仍然会不断递增前进。
所以,这就是为什么需要分别在两个地方储存SCN。
2 正常shutdown database后,SCN会发生什么变化?
当clean shutdown 时,checkpoint会进行,并且此时datafile的stop scn和start scn会相同。 等到我门开启数据库时,Oracle检查datafile header中的start scn和存于control file中的datafile的scn是否相同, 如果相同,接着检查start scn和stop scn是否相同,如果仍然相同,数据库就会正常开启,否则就需要recovery… 等到数据库开启后,储存在control file中的stop scn就会恢复为NULL值,此时表示datafile是open在正常模式下了。
如果不正常SHUTDOWN (shutdown abort),则mount数据库后,你会发现stop scn并不是等于其它位置的scn, 而是等于NULL,这表示Oracle在shutdown时没有进行checkpoint,下次开机必须进行crash recovery。
crash recovery
必须先进行roll forward(从redo log file中从目前的start SCN开始,重做后面的已提交之交易)。再从roll back segment 做rollback未完成(dead transaction)交易。检验controlfile中的SCN会等于datafile header的SCN
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/7286.html