SCN用以标识数据库在某个确切时刻提交的版本。在事务提交时,它被赋予一个唯一的标识事务的SCN。SCN同时被作为Oracle数据库的内部时钟机制,可被看做逻辑时钟,每个数据库都有一个全局的SCN生成器。
SCN(System Change Number),也就是通常所说的系统改变号,是数据库中非常重要的一个数据结构。
SCN用以标识数据库在某个确切时刻提交的版本。在事务提交时,它被赋予一个唯一的标识事务的SCN。SCN同时被作为Oracle数据库的内部时钟机制,可被看做逻辑时钟,每个数据库都有一个全局的SCN生成器。
作为数据库内部的逻辑时钟,数据库事务依SCN而排序,Oracle也依据SCN来实现一致性读(Read Consistency)等重要数据库功能。另外对于分布式事务(Distributed Transactions),SCN也极为重要,这里不做更多介绍。
SCN在数据库中是唯一的,并随时间而增加,但是可能并不连贯。除非重建数据库,SCN的值永远不会被重置为0.
一直以来,对于SCN有很多争议,很多人认为SCN是指System Commit Number,而通常SCN在提交时才变化,所以很多时候,这两个名词经常在文档中反复出现。即使在Oracle的官方文档中,SCN也常以System Change/Commit Number两种形式出现。
到底是哪个词其实不是很重要,重要的是需要知道SCN是Oracle内部的时钟机制,Oracle通过SCN来维护数据库的一致性,并通过SCN实施Oracle至关重要的恢复机制。
SCN在数据库中是无处不在,常见的事务表、控制文件、数据文件头、日志文件、数据块头等都记录有SCN值。
冠以不同前缀,SCN也有了不同的名称,如检查点SCN(Checkpint SCN)、Resetlogs SCN等。
1.1.scn的作用
- 读数据的一致性
- 数据库恢复
- Flashback
- Stream
- 等等其他的
sys@WENCHAOD> select dbms_flashback.get_system_change_number,SCN_TO_TIMESTAMP(dbms_flashback.get_system_change_number) from dual;
GET_SYSTEM_CHANGE_NUMBER SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER)
------------------------ ---------------------------------------------------------------------------
1387175 12-MAR-14 11.35.56.000000000 AM
sys@WENCHAOD>
sys@WENCHAOD> select CURRENT_SCN from v$database;
CURRENT_SCN
-----------
1386439
Oracle数据库提供了两种直接查看系统当前SCN的方法,一个是V$DATABASE中的CURRENT_SCN列,另外一个就是通过dbms_flashback.get_system_change_number得到。
1
2
3
4
5
6
|
SQL> col scn for 9999999999999
SQL> SELECT current_scn scn FROM v$ database ;
SCN
--------------
7046242302279
|
1
2
3
4
5
6
|
SQL> col scn for 9999999999999
SQL> SELECT DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER scn FROM DUAL;
SCN
--------------
7046242302616
|
1
2
3
4
5
6
7
8
|
SQL> col scn2 for 9999999999999
SQL> col scn for 9999999999999
SQL> SELECT current_scn scn,
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER scn2
FROM v$ database ;
SCN SCN2
-------------- --------------
7046253210061 7046253210063
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
-- 将SCN转换成时间戳
SQL> SELECT SCN_TO_TIMESTAMP(7046253210061) timestamp FROM DUAL;
TIMESTAMP
---------------------------------------------------------------------------
30-MAR-10 10.53.04.000000000 AM
-- 将时间戳转换成SCN
SQL> SELECT TIMESTAMP_TO_SCN(TO_TIMESTAMP( '30-MAR-10 10.53.04.000000000 AM' ,
'DD-Mon-RR HH:MI:SS.FF AM' )) SCN FROM DUAL;
SCN
--------------
7046253197273
|
SCN遍布数据库的每一个角落。下面列举几个常见和重要的SCN。
操作是否刷新SCN号码
注:1、曾量检查点会更新控制文件checkpoint 条目的LRBA值。不会改变SCN
2、日志切换,假如切换之后将active类型的日志文件切换为inactive,则会更新系统检查点SCN、文件检查点SCN和文件头部检查点SCN。
3、全量检查点会将buffercache全部写到内容,所以日志状态会发生变化,所以会改变系统检查点CSN。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
-- 建立表
CREATE TABLE t ( x INT );
-- 插入数据
BEGIN
FOR i IN 1 .. 5
LOOP
INSERT INTO t VALUES ( i );
COMMIT ;
END LOOP;
END ;
/
-- 查看结果
SQL> SELECT x, ORA_ROWSCN scn,
2 DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) BLOCKNO
3 FROM t ORDER BY 2;
X SCN BLOCKNO
---------- -------------- ----------
1 7046267387297 31002
2 7046267387297 31002
3 7046267387297 31002
4 7046267387297 31002
5 7046267387297 31002
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
-- 建立表
CREATE TABLE t ( x INT ) ROWDEPENDENCIES;
-- 插入数据
BEGIN
FOR i in 1 .. 5
LOOP
INSERT INTO t VALUES ( i );
COMMIT ;
END LOOP;
END ;
/
-- 查看结果
SQL> SELECT x, ORA_ROWSCN scn,
2 DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) blockno
3 FROM t ORDER BY 2;
X SCN BLOCKNO
---------- -------------- ----------
1 7046267390044 31002
2 7046267390046 31002
3 7046267390047 31002
4 7046267390048 31002
5 7046267390050 31002
|