本帖最后由 听海★蓝心梦 于 2012-4-13 14:26 编辑
这周在搜集资料学习ORACLE SCN的相关知识。虽然也做了一些实验,但是感觉理解的还是不系统,
把我的笔记分享出来,希望感兴趣的一起讨论讨论:
帖子点长,现在把PDF传上来:
【听海日志】之SCN与Oracle.pdf
(439.35 KB, 下载次数: 1016)
希望大家多拍砖啊~~
【听海日志】之SCN与Oracle
一、SCN基础
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.
3、SCN相关概念
1、Redo log中的high SCN和low SCN
Oracle的Redo log会顺序纪录数据库的各个变化。一组redo log文件写满后,会自动切换到下一组redo log文件。则上一组redo log的high SCN就是下一组redo log的low SCN。在current log中high SCN为无穷大。可通过查询v$log_history查看 low SCN和 high SCN:
sys@ORCL>select recid,sequence#,first_change#,next_change# from v$log_history;
RECID SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
---------- ---------------------- --------------------
1 2 21,069,995 21,085,568
2 1 21,085,569 21,105,418
3 2 21,105,418 21,132,018
4 3 21,132,018 21,163,953
5 4 21,163,953 21,191,900
6 5 21,191,900 21,209,347
7 6 21,209,347 21,223,812
8 7 21,223,812 21,232,963
9 8 21,232,963 21,263,223
10 9 21,263,223 21,288,586
11 10 21,288,586 21,301,971
12 1 21,300,115 21,324,025
13 2 21,324,025 21,344,131
14 3 21,344,131 21,347,920
15 4 21,347,920 21,369,784
16 5 21,369,784 21,374,509
17 6 21,374,509 21,374,914
18 7 21,374,914 21,375,336
19 8 21,375,336 21,384,136
20 9 21,384,136 21,409,089
21 10 21,409,089 21,446,217
22 11 21,446,217 21,496,982
23 12 21,496,982 21,509,283
24 13 21,509,283 21,545,787
25 14 21,545,787 21,564,418
26 15 21,564,418 21,581,068
27 16 21,581,068 21,582,611
28 17 21,582,611 21,582,860
29 18 21,582,860 21,583,942
30 19 21,583,942 21,609,862
31 20 21,609,862 21,630,988
32 21 21,630,988 21,655,891
32 rows selected.
2、查看currnet redolog中的high SCN
sys@ORCL>select vf.member,v.status,v.first_change# from v$logfile vf,v$log v wherevf.group#=v.group# and v.status='CURRENT';
MEMBER STATUS FIRST_CHANGE#
------------------------------------------------------------------------------------------------------------------
/opt/oracle/oradata/orcl/redo01.log CURRENT 21,655,891
sys@ORCL> altersystem dump logfile '/opt/oracle/oradata/orcl/redo01.log';
System altered.
sys@ORCL> showparameter user_dump
NAME TYPE VALUE
----------------------------------------------- ------------------------------
user_dump_dest string /opt/oracle/diag/rdbms/orcl/orcl/trace
打开转储出来的文件,可以看到:
DUMP OF REDO FROM FILE'/opt/oracle/oradata/orcl/redo01.log'
Opcodes *.*
RBAs: 0x000000.00000000.0000 thru0xffffffff.ffffffff.ffff
SCNs: scn: 0x0000.00000000 thru scn:0xffff.ffffffff
Times: creation thru eternity
FILE HEADER:
CompatibilityVsn = 186646528=0xb200000
DbID=1284637334=0x4c920296, Db Name='ORCL'
ActivationID=1296530476=0x4d477c2c
ControlSeq=19392=0x4bc0, File size=102400=0x19000
FileNumber=1, Blksiz=512, File Type=2 LOG
descrip:"Thread 0001, Seq# 0000000022,SCN 0x0000014a7153-0xffffffffffff"
thread: 1 nab: 0xffffffff seq: 0x00000016 hws:0x5 eot: 1 dis: 0
resetlogs count: 0x2dd248e0 scn:0x0000.01450393 (21300115)
prev resetlogs count: 0x2dce6ef7 scn:0x0000.0141bd81 (21085569)
Low scn: 0x0000.014a7153 (21655891)03/20/2012 09:18:56
Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
Enabled scn: 0x0000.01450393 (21300115)12/01/2011 15:18:56
Thread closed scn: 0x0000.014a7953 (21657939)03/20/2012 09:43:56
Disk cksum: 0x202e Calc cksum: 0x202e
Terminal recovery stop scn: 0x0000.00000000
Terminal recovery 01/01/1988 00:00:00
Most recent redo scn: 0x0000.00000000
Largest LWN: 0 blocks
End-of-redo stream : No
Unprotected mode
Miscellaneous flags: 0x800000
Thread internal enable indicator: thr: 0, seq:0 scn: 0x0000.00000000
redo log中当前系统的SCN记录当前最新的数据库SCN值可通过如下命令查看:
sys@ORCL>select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
21658581
如果需要进行实例恢复,则需恢复的记录为21655891至21658581中redo log中的记录。
3、日志切换或者checkpoint
当日志切换或发生checkpoint时,从Low SCN到Next SCN之间的所有redo记录的数据就被DBWn进程写入数据文件中,而CKPT进程则将所有数据文件(无论redo log中的数据是否影响到该数据文件)的文件头上记录的Start SCN(通过视图v$datafile_header的字段checkpoint_change#可以查询)更新为Next SCN,同时将控制文件中的System Checkpoint SCN(通过视图v$database的字段checkpoint_change#可以查询)、每个数据文件对应的DatafileCheckpoint(通过视图v$datafile的字段checkpoint_change#可以查询)也更新为Next SCN。但是,如果该数据文件所在的表空间被设置为read-only时,数据文件的Start SCN和控制文件中DatafileCheckpoint SCN都不会被更新。
4、心跳
在Oracle中有一个事件叫Heartbeat,这个词在很多地方被提及,并且有着不同的含义(比如RAC中),我们这里要讨论的是CKPT的Heartbeat机制。Oracle通过CKPT进程每3秒将Heartbeat写入控制文件,以减少故障时的恢复时间。
5、数据库正常关闭启动
数据库正常关闭时,系统会执行一个完全检查点动作,并用该检查点时的SCN号更新上述4个SCN号,这时所有数据文件的终止SCN号会设置为数据文件头的那个启动SCN(除了离线和只读的数据文件)。
数据库重新启动时,Oracle将数据文件头中的启动SCN与数据文件检查点SCN比较,如果这两个值匹配,Oracle接下来再比较数据文件头中的SCN和控制文件中数据文件的终止SCN,如果这个值也匹配,就意味着所有数据块已经提交,因此数据库不需要进行恢复,此时数据库直接打开。当所有的数据文件都打开之后,在线且可读写的数据文件终止SCN再次被设置为NULL,表示数据文件已经打开并能够正常使用了。有些表空间是只读的,这时控制文件中的系统检查点SCN号会不断增长,而数据文件SCN号和文件头中的启动SCN(会停止更新直到表空间又设置为可读写),显然这时系统检查点SCN号会大于数据文件SCN和文件头启动SCN。
6、数据库非正常关闭
数据库非正常关闭(或称为实例崩溃)时,终止SCN不会被设置,依然为NULL,这可以通过把数据库启动至mount状态查询出来。这样重新启动时,SMON进程会执行实例恢复工作,即先执行前滚,再把数据库打开,最后执行回滚操作。
7、数据文件介质故障
出现介质故障时,数据文件检查点SCN及系统检查点SCN比文件头启动SCN大。系统发生介质故障时,数据文件被以前的备份代替,控制文件中的数据文件检查点SCN肯定比文件头中的启动SCN要大,这样Oracle就知道要对这个文件进行介质恢复。
8、控制文件介质故障
系统检查点SCN及数据文件SCN比数据文件头启动SCN小:
在数据库恢复时,控制文件可能不是最新的,即把一个较早的控制文件还原为当前的控制文件,然后再执行恢复操作,这时控制文件中的系统检查点SCN和数据文件SCN可能比文件头的启动SCN小。这时恢复数据库要用下面命令:recover database using Backup Controlfile或其他的恢复语句。
9、备份时的实例崩溃当执行begin backup时实例崩溃:控制文件中的数据文件检查点SCN号和数据文件头部检查点SCN号相同,但是每个可读写的在线数据文件之间检查点SCN号不同,那么要求介质恢复,例如发出beginbackup命令后就会出现这种情况,需要通过endbackup命令好才可以打开数据库。
|