Oracle SCN详解

SCN是Oracle中一个很基础的部分,但同时它也是一个很重要的数据:它是系统中维持数据的一致性和顺序恢复的重要标志,是数据库非常重要的一种数据结构。


一,SCN介绍
SCN即系统改变号(System Change Number),是在某个时间点定义数据库已提交版本的时间戳标记。 Oracle为每个已提交的事务分配一个唯一的SCN。 SCN的值是对数据库进行更改的逻辑时间点。 Oracle使用此编号记录对数据库所做的更改。
在数据库中,SCN也可以说是无处不在,数据文件头,控制文件,数据块头,日志文件等等都标记着SCN。也正是这样,数据库的一致性维护和SCN密切相关。不管是数据的备份,恢复都是离不开SCN的。


SCN是一个6字节(48bit)的数字,其值为281,474,976,710,656(2^48),分为2个部分
1. SCN_BASE :
是一个4字节(32bit)的数字
2. SCN_WRAP :
是一个2字节(16bit)的数字
每当SCN_BASE达到其最大值(2^32 = 4294967296)时,SCN_WRAP增加1,SCN_BASE将被重置为0,一直持续到SCN_WRAP达到其最大值,即2^16 = 65536。
SCN =(SCN_WRAP * 4294967296)+ SCN_BASE
SCN随着每个事务的完成而增加。
提交不会写入数据文件,也不更新控制文件。
当发生checkpoint时,控制文件更新,SCN被写入到控制文件。
当前的SCN可以通过以下查询获得:
select dbms_flashback.get_system_change_number scn from dual; select current_scn from v$database;


二,四种重要的SCN
在理解这几种SCN之前,我们先看下oracle事务中的数据变化是如何写入数据文件的:
第一步:事务开始;
第二步:在buffer cache中找到需要的数据块,如果没找到,从数据文件中载入buffer cache中;
第三步:事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;
第四步:事务提交,LGWR进程将log buffer中的“脏数据”的日志条目写入redo log file中;
第五步:当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWn进程则负责将Buffer Cache中的脏数据写入到数据文件中。
经过上述5个步骤,事务中的数据变化最终被写入到数据文件中。

但是,一旦在上述中间环节数据库意外宕机了,在重新启动时如何知道哪些数据已经写入数据文件、哪些没有写呢?(同样,在DG、streams中也存在类似疑问:redolog中哪些是上一次同步已经复制过的数据、哪些没有)

SCN机制就能比较完善的解决上述问题。

SCN是一个数字,确切的说是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了 Oracle知道哪些应该被恢复、哪些应该被复制。

总共有4种SCN:

• 系统检查点(System Checkpoint)SCN
• 数据文件检查点(Datafile Checkpoint)SCN
• 结束SCN(Stop SCN)
• 开始SCN(Start 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将StartSCN存放在数据文件头中。这个SCN用于检查数据库启动过程是否需要做media recovery。我们可以通过以下SQL语句查询:
select name,checkpoint_change# from v$datafile_header;
(4)Stop SCN
ORACLE将StopSCN存放在控制文件中。这个SCN号用于检查数据库启动过程是否需要做instance recovery。我们可以通过以下SQL语句查询:
select name,last_change# from v$datafile;
在数据库正常运行的情况下,对可读写的online数据文件,该SCN号为NULL。
SCN与数据库启动:
在nce recov数据库启动过程中,当System Checkpoint SCN、Datafile Checkpoint SCN和Start SCN都相同时,数据库可以正常启动,不需要做media recovery。
• 三者当中有一个不同时,则需要做media recovery。
• 如果在启动的过程中,End SCN为NULL,则需要做instance recovery。
Oracle在启动过程中首先检查是否需要media recovery,然后再检查是否需要instaery。
SCN与数据库关闭:
如果数据库的正常关闭的话,将会触发一个checkpoint,同时将数据文件的END SCN设置为相应数据文件的Start SCN。
当数据库启动时,发现它们是一致的,则不需要做instance recovery。
在数据库正常启动后,ORACLE会将END SCN设置为NULL.如果数据库异常关闭的话,则END SCN将为NULL。


为什么ORACLE在控制文件中记录System checkpoint SCN 号的同时,还需要为每个数据文件记录DatafileCheckpoint SCN?
如果有表空间read only,那么该表空间的所有datafile的start SCN和stop SCN将被冻结,这个时候就跟System Checkpoint SCN不一致,但在库open的时候是不需要做media recovery的,如果没有DatafileCheckpoint SCN就无法判断这些datafile是否是最新的。

总结:

system checkpoint scn — 存放在controlfile中
datafile checkpoint scn –存放在controlfile中
start scn —存放在datafile header中
stop scn —存放在controlfile中

SCN号与数据库启动
1)检查是否需要介质恢复
在数据库启动过程中,当System Checkpoint SCN、Datafile Checkpoint SCN和
Start SCN号都相同时,数据库可以正常启动,不需要做media recovery。三者当中有一个不同时,则需要做media recovery.
2)检查是否需要实例恢复
如果在启动的过程中,End SCN 号为NULL,则需要做instance recovery.
ORACLE在启动过程中首先检查是否需要media recovery,然后再检查是否需要
instance recovery.
5. SCN号与数据库关闭
如果数据库的正常关闭的话,将会触发一个checkpoint,同时将数据文件的END SCN
号设置为相应数据文件的Start SCN号。
当数据库启动时,发现它们是一致的,则不需要做instance recovery。在数据库正常启动后,ORACLE会将END SCN 号设置为NULL.
如果数据库异常关闭的话,则END SCN号将为NULL.
6.为什么需要System SCN号与Datafile号
为什么ORACLE会在控制文件中记录System checkpoint SCN 号的同时,还需要为每个数据文件记录Datafile Checkpoint SCN 号?
1)对只读表空间,其数据文件的Datafile Checkpoint SCN、Start SCN和END SCN号均相同。这三个SCN在表空间处于只读期间都将被冻结。
2)如果控制文件不是当前的控制文件,则System checkpoint会小于Start SCN或END SCN号。记录这些SCN号,可以区分控制文件是否是当前的控制文件。 

原文链接:https://blog.csdn.net/qq_34556414/article/details/79493934

原文地址:https://www.cnblogs.com/muzisanshi/p/11940266.html