Oracle SCN (System change number)

http://www.itpub.net/thread-1601493-1-1.html

 

 

1、什么是SCN

 

Concepts中是这样描述SCN的:

A system change number (SCN) is alogical, internal timestamp used by Oracle Database. SCNs order events thatoccur within the database, which is necessary to satisfy the ACID properties ofa transaction. Oracle Database uses SCNs to mark the SCN before which allchanges are known to be on disk so that recovery avoids applying unnecessaryredo. The database also uses SCNs to mark the point at which no redo exists fora set of data so that recovery can stop.

 

怎么理解这个“SCN(系统变更号)是供Oracle数据库使用的一个逻辑的、内部的时间戳”呢?要理解这个先需要理解Oracle中的事务(Transaction)和数据一致性(Data Consistency)的概念。

 

先说说数据一致性的概念。数据一致性指的是数据的可用性。比如说管理一个财务的系统,需要从A账户将100元转入到B账户,正常的操作是从A账户减去100元,然后给B账户加上100元,如果这两步操作都正常完成了,那我们可以说完成转账操作之后的数据是一致可用的;但是如果在操作的过程中出了问题,A账户的100元给减掉了,但是B账户却没有加上100元,这样的情况下产生的结果数据就有问题了,因为部分操作的失败导致了数据的不一致而不可用,在实际中肯定是要避免这种让数据不一致的情况发生的。在Oracle数据库中,保证数据一致性的方法就是事务。

 

事务是一个逻辑的、原子性的作业单元,通常由一个或者是多个SQL组成,一个事务里面的所有SQL操作要么全部失败回滚(Rollback),要么就是全部成功提交(Commit)。就像上面转账的例子,为保证数据的一致性,就需要将转账的两步操作放在一个事务里面,这样不管哪个操作失败了,都需要将所有已进行的操作回滚,以保证数据的可用性。进行事务管理是数据库区别于别的文件系统的一个最主要的特征,在数据库中事务最主要的作用就是保证了数据的一致性,每次事务的提交都是将数据库从一种一致性的状态带入到另外一种一致性的状态中,SCN就是用来对数据库的每个一致状态进行标记的,每当数据库进入到一个新的一致的状态,SCN就会加1,也就是每个提交操作之后,SCN都会增加。也许你会想为什么不直接记录事务提交时候的时间戳呢?这里面主要是涉及了两个问题,一个是时间戳记录的精度有限,再一个就是在分布式系统中记录时间戳会存在系统时钟同步的问题,详细的讨论可以查看Ordering Events in Oracle。

 

SCN在数据库中是一个单一的不断的随着数据库一致性状态的改变而自增的序列。正如一个时间戳代表着时间里面的某一个固定的时刻点一样,每一个SCN值也代表着数据库在运行当中的一个一致性的点,大的SCN值所对应的事务总是比小SCN值的事务发生的更晚。因此把SCN说成是Oracle数据库的逻辑时间戳是很恰当的。

 

 

2、SCN概述 

 

SCN是当Oracle数据库更新后,由DBMS去自动维护累积递增的一个数字。通常看文章的时候能看到各种类型的SCN,但是严格来说SCN是没有分类的,之所以会有不同类型的SCN并不是说这些SCN的概念不一样,而是说不同分类的SCN代表的意义不一样,不管什么时候SCN所指代的都是数据库的某个一致性的状态。就像我们给一天中的某个时间点定义上班时间、另外的某个时间点定义成下班时间一样,数据库Checkpoint发生点的SCN被称为Checkpoint SCN,仅此而已。Oracle数据库中一共有4种SCN分别为:

 

•系统检查点SCN (System Checkpoint SCN)

•文件检查点SCN (Datafile Checkpoint SCN)

•结束SCN (Stop SCN)

•数据文件头SCN (Start SCN)

 

其中前面3中SCN存在于控制文件中,最后一种则存在于数据文件的文件头中,在Oracle中用来标识数据库的每一次改动,及其先后顺序,SCN的最大值是0xffff.ffffffff。在控制文件中,SystemCheckpoint SCN是针对整个数据库全局的,因而只存在一个,而Datafile Checkpoint SCN和Stop SCN是针对每个数据文件的,因而一个数据文件就对应在控制文件中存在一份Datafile Checkpoint SCN和Stop SCN。在数据库正常运行期间,Stop SCN(通过视图v$datafile的字段last_change#可以查询)是一个无穷大的数字或者NULL。

 

 

1、系统检查点SCN

 

系统检查点SCN位于控制文件中,当检查点进程启动时(ckpt),Oracle就把系统检查点的SCN存储到控制文件中。该SCN是全局范围的,当发生文件级别的SCN时,例如将表空间置于只读状态,则不会更新系统检查点SCN。查询系统检查点SCN的命令如下:

 

sys@ORCL>select CHECKPOINT_CHANGE# from v$database;

CHECKPOINT_CHANGE#

------------------

        21655892

 

2、文件SCN

 

当ckpt进程启动时,包括全局范围的(比如日志切换)以及文件级别的检查点(将表空间置为只读、begin backup或将某个数据文件设置为offline等),这时会在控制文件中记录的SCN。查询数据文件SCN的命令如下:

 

sys@ORCL> altertablespace users read only;

Tablespace altered.

sys@ORCL>select file#,checkpoint_change# from v$datafile;

     FILE# CHECKPOINT_CHANGE#

---------- ------------------

       1        21655892

       2        21655892

       3        21655892

       4        21657577

       5        21657577

       6        21655892

6 rows selected.

 

sys@ORCL>select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#

------------------

        21655892

 

可以看到4、5号文件也就是users表空间所属的文件SCN值和其他文件不一致,且比系统检查点的SCN要大(因为这两个数据文件最后被操作,其他数据文件没有变动)。

 

 

3、结束SCN

 

每个数据文件都有一个结束SCN,在数据库的正常运行中,只要数据文件在线且是可读写的,结束SCN为NULL。否则则存在具体的SCN值。结束SCN也记录在控制文件中。

 

sys@ORCL>select TABLESPACE_NAME,STATUS from dba_tablespaces;

TABLESPACE_NAME              STATUS

----------------------------------------------

SYSTEM                         ONLINE

SYSAUX                         ONLINE

UNDOTBS1                    ONLINE

TEMP                        ONLINE

USERS                           READ ONLY

 

sys@ORCL>select file#,LAST_CHANGE# from v$datafile;         

     FILE# LAST_CHANGE#

---------- ------------

       1

       2

       3

       4     21657577

       5     21657577

       6

 

6 rows selected.

 

可以看到除了users表空间的结束SCN不为空,其他数据文件的结束SCN为空。将数据库至于mount状态,由于该状态下所有的数据文件都不可写,故mount状态下所有的数据文件都具有结束SCN。

 

sys@ORCL>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

 

sys@ORCL>startup mount

ORACLE instance started.

Total System Global Area  263049216 bytes

Fixed Size              2212448 bytes

Variable Size              230690208 bytes

Database Buffers        25165824 bytes

Redo Buffers               4980736 bytes

 

Database mounted.

 

sys@ORCL>select file#,last_change# from v$datafile;

 

     FILE# LAST_CHANGE#

---------- ------------

       1    21657939

       2    21657939

       3    21657939

       4    21657577

       5    21657577

       6    21657939

 

6 rows selected.

 

4、数据文件头SCN

 

不同于上述的SCN数据文件开始SCN记录在每个数据文件中。当发生系统及文件级别的检查点后,不仅将这时的SCN号记录在控制文件中,同样也记录在数据文件中。查询数据文件头SCN的命令如下:

 

sys@ORCL>select file#,CHECKPOINT_CHANGE# from v$datafile_header;

 

FILE# CHECKPOINT_CHANGE#

 

---------- ------------------

       1        21657939

       2        21657939

       3        21657939

       4        21657577

       5        21657577

       6        21657939

 

6 rows selected.

 

 

当数据库用 normal 或者 immediate 选项关闭时,执行检查点,更新控制文件中数据文件的 stop scn,等于数据文件头中的 checkpoint scn。

下次启动数据库时,oracle 要进行两次检查。第一次看数据文件头中的 checkpoint scn 与控制文件中数据文件的 checkpoint scn。如果相等,进行第二次检查,检查数据文件头中的 checkpoint scn 与控制文件中数据文件的 stop scn。如果相等,不需要对这个文件恢复。每个数据文件都做这样的检查,然后打开数据库,将每个 stop scn 重新置为无穷大。

如果用 abort 关闭数据库,则不执行检查点处理,控制文件中数据文件的 stop scn 仍为无穷大。

下次启动时做两次检查。如第一次相等,再比较第二个。这时,数据文件头中的 checkpoint scn 一定是小于控制文件中数据文件的 stop scn 的,需要进行崩溃/实例恢复,进行前滚和回滚。

如果用备份代替了数据文件再启动数据库,这时做第一次检查时,数据文件头中的 checkpoint scn 一定小于控制文件中数据文件的 checkpoint scn;或者用备份的控制文件代替了控制文件再启动数据库,这时数据文件头中的 checkpoint scn 一定大于控制文件中数据文件的 checkpoint scn。只要这两个不相等,就需要介质恢复。

还有一种情况,如果控制文件和数据文件都是备份的,而这两个 checkpoint scn 正好相等,第一次比较通过,那么再看第二次比较了。其实这个时候在第一次比较之前,会先比较控制文件中 redo 线程的 checkpoint scn 的和 online log 的 scn,如果相等,继续,如果不相等(小于),提示控制文件是旧的需要介质恢复。

猜你喜欢

转载自buralin.iteye.com/blog/1773450
SCN