概述
1.什么是scn?
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
- 等等其他的
2.scn如何产生?
SCN是一个由之间转换过来的数字,可以通过下列语句转换SCN和具体时间。
SELECTDBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER,
SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER)FROM DUAL;
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
2.1.SCN查看与转换
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
|
2.2.SCN与时间的相互转换
-
SCN_TO_TIMESTAMP(scn_number)
- 将SCN转换成时间戳。 TIMESTAMP_TO_SCN(timestamp)
- 将时间戳转换成SCN。
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
|
3.常见scn
SCN遍布数据库的每一个角落。下面列举几个常见和重要的SCN。
1、系统检查点SCN(控制文件数据库条目)
可以通过查询视图获得系统检查点SCN值,该值保存在控制文件中,SELECT CHECKPOINT_CHANGE# FROM V$DATABASE; 表示的是LAST SCNCHECKPOINTED。可以通过dump出控制文件进行查看:ALTERSESSION SET EVENTS 'IMMEDIATE TRACE NAME CONTROLF LEVEL 12'。
2、文件检查点SCN(控制文件数据文件条目)
可以通过查询视图获得文件检查点SCN值,该值保存在控制文件中,SELECTNAME,CHECKPOINT_CHANGE# FROM V$DATAFILE;可以通过dump出控制文件进行查看:ALTERSESSION SET EVENTS 'IMMEDIATE TRACE NAME CONTROLF LEVEL 12'。
3、文件最终检查点SCN(控制文件数据文件条目)
可以通过查询视图获得文件最终检查点SCN值,该值保存在控制文件中,SELECTNAME,LAST_CHANGE# FROM V$DATAFILE;改值在数据库启动时设置为无穷大,该值在数据库正常关闭的情况下设置为关闭时的SCN,非正常关闭依旧为无穷大。4、数据文件头部的检查点SCN(数据文件头)
可以通过查询视图获得文件检查点SCN值,该值保存在数据文件头部,SELECT NAME,CHECKPOINT_CHANGE# FROM V$DATAFILE_HEADER。也可以通过dump数据文件头块进行查看。5、RedoFile文件开始SCN
表示切换到该日志文件的时间点,可以通过查询视图获得文件RedoFile文件开始SCN,该值保存在数据文件头部,SELECT FIRST_CHANGE# FROM V$LOG; 也可以通过dump redoFile文件头块进行查看。当前redoFile的开始SCN就是上一个redoFile的的结束SCN。6、RedoFile文件结束SCN
表示切换到下一个日志文件的时间点,可以通过查询视图获得文件RedoFile文件开始SCN,该值保存在数据文件头部,SELECT NEXT_CHANGE# FROM V$LOG; 也可以通过dump redoFile文件头块进行查看。当前redoFile的结束SCN就是下一个redoFile的的开始SCN。7、RedoLog条目的SCN
表示redo条目对应数据库被修改时间点的CSN。4.各检查点之间关系
1、数据库正常关闭和启动时,控制文件的系统SCN、控制文件中的数据文件开始SCN和数据文件头部的开始SCN是相等的,文件的最终检查点SCN是无穷大。2、正常关闭数据库,oracle会做下列操作。
A、将所有的buffer cache写到磁盘上。
B、用关闭的时间点SCN更新系统SCN、文件检查点SCN、文件最终检查点SCN、数据文件头部检查点SCN。此时4中SCN的值相同。
3、数据库非正常关闭(abort),数据库不做写buffercache操作和更新SCN操作。此时文件最终检查点依然为空,数据库需要进行实例恢复。数据库在open的过程中,从控制文件的检查点条目中的每个检查点队列中取得LRBA(检查点队列中第一个脏块的LRBA)和ON DISK RBA(对应REDO FILE的最后一条redolog 条目),然后从LRBA跑日志到ON DISK RBA。
4、数据库正常关闭,用一个备份的数据文件覆盖其中一个数据文件,此时数据文件头部的检查点SCN小于控制文件中的“文件检查点SCN”,此时就需要进行介质恢复。
操作对SCN号的影响
操作是否刷新SCN号码
注:1、曾量检查点会更新控制文件checkpoint 条目的LRBA值。不会改变SCN
2、日志切换,假如切换之后将active类型的日志文件切换为inactive,则会更新系统检查点SCN、文件检查点SCN和文件头部检查点SCN。
3、全量检查点会将buffercache全部写到内容,所以日志状态会发生变化,所以会改变系统检查点CSN。
5.ORA_ROWSCN伪列
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
|
6. 检查点和SCN
二、增量检查点:当增量检查点发生时:
1、ckpt进程会把检查点队列的第一个被脏的数据块所对应的日志地址记录到控制文件。
2、当检查点队列连接的脏块太多以及系统的I/O不是很忙,这是会触发DBwriter将最早脏的数据块部分写入磁盘上来缩短检查点队列。
三、当Oracle正常关闭时会触发完全检查点,当Oracle在正常运行期间每隔3秒发生一次增量检查点。
四、每个数据块中都有两个日志地址:LRBA和HRBA
RBA:数据块日志地址
LRBA:数据块第一次被脏的日志地址
HRBA:数据块最近一次被脏的日志地址
五、检查点队列:把数据块按其LRBA地址连接起来的。
注:日志是按时间顺序记录buffer cache的变化,所以检查点队列中数据块是按照其第一次被脏的时间排序的(数据块第一次被脏的时间越早就越靠前,越迟就越靠后)。
六、Log writer进程每隔3秒会将log buffer cache里面的日志写到当前联机日志里(current redo log)。
七、on disk RBA:是current redo log里面的最后一条日志的地址(即current redo log 里面最新一条日志的地址)。
八、实例崩溃恢复过程(Oracle自动恢复):找起点,确定终点,跑日志(前滚)
1、Oracle发现实例非正常关闭需要做实例恢复
2、Oracle在控制文件中通过LRBA地址找到日志的起点
3、Oracle从日志的起点开始跑,跑到redo log的最后一条日志
4、Oracle跑日志跑到终点时,保证所有已提交事物的脏块全部被构造出来,同时一些未提交事物的脏块也被构造出来,Oracle会自动将崩溃前为提交的事物进行回滚
注:实例恢复需要联机日志(不需要归档日志)
九、SCN(system change number)
1、将系统时间通过一个函数转变为一个数字,就是SCN
2、查看当前SCN和时间
scn:select dbms_flashback.get_system_change_number,SCN_TO_TIMESTAMP
(dbms_flashback.get_system_change_number) from dual;
3、常见SCN号:
A、控制文件中:系统SCN、文件SCN、结束SCN
①系统SCN:select checkpoint_change# from v$database;
②文件SCN:select name,checkpoint_change# from v$datafile;
③结束SCN:select name,last_change# from v$datafile;
B、数据文件头部:起始SCN
select name,checkpoint_change# from v$datafile_header;
C、日志文件:
①每个日志文件头部都有first、next两个SCN
select * from v$log;
注:
first SCN就是一个日志文件里面第一条日志的SCN
next SCN就是下一个日志文件里面的第一条日志的SCN
②每条日志里面都有个SCN
D、SCN知识点
①数据库正常启动时,控制文件中系统SCN、文件SCN和数据文件中的起始SCN号应该是相
同的,结束SCN是空(可以理解为无穷大)。
②数据库正常关闭时,用关闭的时间点SCN去更新控制文件中系统SCN、文件SCN、结束
SCN和数据文件中的起始SCN。
③数据库非正常关闭时,控制文件中系统SCN、文件SCN和数据文件中起始SCN为崩溃时的
时间点的SCN,而控制文件中的结束SCN为空,下次启动时,Oracle检查到系统SCN、文件
SCN和起始SCN一样,唯独结束SCN为空,则认为需要做实例恢复。
④数据库正常运行时,当发生脏块写入磁盘时,及redo log里面的active(日志所对应
的脏缓存区还没写入磁盘)变为inactive(日志所对应的脏缓存区已经写入磁盘),则ckpt会用redo log里最老的active的first SCN更新系统SCN、文件SCN和起始SCN。
⑤当用旧的数据文件、控制文件替代新的,然后启动数据库,Oracle发现控制文件里面的系统SCN和current redo log的SCN低,则Oracle会通过跑日志,把旧的数据文件,控制文件跑成最新。
最后
以上就是大胆钥匙为你收集整理的oracle scn详解1.什么是scn?2.scn如何产生?3.常见scn4.各检查点之间关系5.ORA_ROWSCN伪列6. 检查点和SCN 的全部内容,希望文章能够帮你解决oracle scn详解1.什么是scn?2.scn如何产生?3.常见scn4.各检查点之间关系5.ORA_ROWSCN伪列6. 检查点和SCN 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复