[转]关于SCN写的很详细的一篇文章

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

这是我读过写的比较好的那一类:

数据变化是如何写入数据文件的
在理解SCN之前,我们先看下ORACLE事务中的数据变化是如何写入数据文件的:
1.事务开始;
2.在BUFFER CACHE中寻找需要的数据块,如果没有,则从数据文件读入数据块;
3.生成重做项写入REDO LOG BUFFER(重做日志缓冲区)中,修改BUFFER CACHE(数据库高速缓冲区),该区域被标识为“脏缓冲区”;
4.事务提交,LGWR进程将LOG BUFFER中的重做记录写入ONLINE REDO LOG
FILE(联机重做日志文件)中;
5.当发生CHECKPOINT,CKPT进程更新所有数据库文件头的信息,DBWn进程将BUFFER CACHE中的脏数据写入DATA FILE中。

 

经过上述5个步骤,事务中的数据变化最终被写入到数据文件中。
但是,一旦在上述中间环节时,数据库意外宕机了,那么在重新启动时,ORACLE如
何知道哪些数据已经写入数据文件,哪些没有写呢?
我们知道,SCN机制能比较完善的解决上述问题。
相对我们人类用世纪、年月日、时分秒计时而言,SCN就相当于ORACLE的计时方法。
SCN是一个数字,确切的说是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了Oracle知道哪些应该被恢复、哪些应该被复制。
总共有4中SCN:
系统检查点(System Checkpoint)SCN、数据文件检查点(Datafile Checkpoint)
SCN、结束SCN(Stop SCN)、开始SCN(Start SCN)。 

最新SCN和四种SCN
1.系统最新SCN
SQL> select current_scn from v$database;
CURRENT_SCN
----------------------
847164
//通过查询可以发现,该SCN一直在发生变化,是系统最新的SCN号。 

System Checkpoint SCN(系统检查点SCN)
当checkpoin(检查点)完成后,ORACLE将System Checkpoint SCN号(系统检查点SCN)存放在控制文件中。
我们可以通过下面SQL语句查询:
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
-----------------------------------
846888
//通过查询可以发现,该SCN没有发生变化,并且小于系统最新的SCN号。
//执行检查点
SQL> alter system checkpoint;
System altered.
//查询系统检查点SCN
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------------------------
847491
//查询系统当前SCN
SQL> select current_scn from v$database;
CURRENT_SCN
----------------------
847495
//通过以上实验可以发现,系统检查点SCN根据检查点发生变化,即当前数据
库同步状态的SCN。 

Datafile Checkpoint SCN(数据文件检查点SCN)
当checkpoint完成后,ORACLE将Datafile Checkpoint SCN 号存放在控制文件中。
我们可以通过下面SQL语句查询所有数据文件的Datafile Checkpoinnt SCN号。
SQL> select name,checkpoint_change# from v$datafile;
NAME CHECKPOINT_CHANGE#
------------------------------------------------------------ ----------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf 847491
/u01/app/oracle/oradata/orcl/sysaux01.dbf 847491
/u01/app/oracle/oradata/orcl/undotbs01.dbf 847491
/u01/app/oracle/oradata/orcl/users01.dbf 847491
/u01/app/oracle/oradata/orcl/example01.dbf 847491
//我们发现,每个数据文件都有一个对应的数据文件检查点SCN号。 

Start SCN号(开始SCN)
ORACLE将Start SCN号存放在数据文件头中。
这个SCN用于检查数据库启动过程是否需要做media recovery(介质恢复).
我们可以通过以下SQL语句查询:
SQL> select name,checkpoint_change# from v$datafile_header;
NAME CHECKPOINT_CHANGE#
------------------------------------------------------------ ----------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf 847491
/u01/app/oracle/oradata/orcl/sysaux01.dbf 847491
/u01/app/oracle/oradata/orcl/undotbs01.dbf 847491
/u01/app/oracle/oradata/orcl/users01.dbf 847491
/u01/app/oracle/oradata/orcl/example01.dbf 847491
//我们发现,每个数据文件都有一个对应的开始SCN号,并和前面保持一致。
//将表空间example脱机。
SQL> alter tablespace example offline;
Tablespace altered.
//执行检查点
SQL> alter system checkpoint;
System altered. 

SQL> select name,checkpoint_change# from v$datafile_header;
NAME CHECKPOINT_CHANGE#
------------------------------------------------------------ ----------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf 848249
/u01/app/oracle/oradata/orcl/sysaux01.dbf 848249
/u01/app/oracle/oradata/orcl/undotbs01.dbf 848249
/u01/app/oracle/oradata/orcl/users01.dbf 848249
0
//我们看到,被脱机的表空间对应的数据文件头部的SCN无法读取到。
SQL> select name,checkpoint_change# from v$datafile;
NAME CHECKPOINT_CHANGE#
------------------------------------------------------------ ----------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf 848249
/u01/app/oracle/oradata/orcl/sysaux01.dbf 848249
/u01/app/oracle/oradata/orcl/undotbs01.dbf 848249
/u01/app/oracle/oradata/orcl/users01.dbf 848249
/u01/app/oracle/oradata/orcl/example01.dbf 848238
//我们看到,被脱机的表空间对应的数据文件存在控制文件头部的SCN保留在我们脱机的那一时间。

Stop SCN号(结束SCN)
ORACLE将Stop SCN 号存放在控制文件中。
这个SCN号用于检查数据库启动过程是否需要做instance recovery(实例恢复)。
我们可以通过以下SQL语句查询:
SQL> select name,last_change# from v$datafile;
NAME LAST_CHANGE#
------------------------------------------------------------ ----------------------------------
/u01/app/oracle/oradata/orcl/system01.dbf
/u01/app/oracle/oradata/orcl/sysaux01.dbf
/u01/app/oracle/oradata/orcl/undotbs01.dbf
/u01/app/oracle/oradata/orcl/users01.dbf
/u01/app/oracle/oradata/orcl/example01.dbf 848238
//在数据库正常运行的情况下,对可读写的 online 的数据文件,该 SCN 号为 NULL。 

三、过程详解
四种SCN中,3种SCN存在于控制文件中,Start SCN则存在于数据文件的文件头中。在控制文件中,System Checkpoint SCN是针对整个数据库全局的,因而只存在一个,而Datafile Checkpoint SCN和Stop SCN是针对每个数据文件的,因而一个数据文件就对应在控制文件中存在一份Datafile Checkpoint SCN和Stop SCN。 

1. STOP SCN的变化
在数据库正常运行期间,Stop SCN(通过视图v$datafile的字段last_change#可以查询)是一个无穷大的数字或者说是NULL。 

 

记录日志时,自动记录最新的SCN到日志中。因此,每一条日志都包含了一个时间。
当DBWn进程启动时,将依照日志记录写入一段数据。这一段日志记录的时间段必定有一个最早时间和一个最新(迟)时间。最早的时间我们称为LOW SCN(即上次清空日志后的第一条记录),最新时间我们称为NEXT SCN(即下次日志清空前的最近一条记录)。
这里, 由CKPT进程将 NEXT SCN的值同步更 新 到 START SCN、SYSTEM CHECKPOINT SCN 和DATAFILE CHECKPOINT SCN中。以确保所有文件的一致性。
3.最新的SCN如何生成
系统是如何产生一个最新的SCN的?实际上,这个数字是由当时的timestamp转换过来的。每当需要产生一个最新的SCN到redo记录时,系统获取当时的timestamp,将其转换为数字作为SCN。 

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号,可以区分控制文件是否是当前的控制文件。 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值