SCN的定义
SCN(System Change Number),也就是通常所说的系统改变号,是数据库中非常重要的一个数据结构。
SCN用以标识数据库在某个确切时刻提交的版本。在事务提交时,它被赋予一个惟一的标识事务的SCN。SCN同时被作为oracle数据库的内部时钟机制,可被看作逻辑时钟,每个数据库都有一个全局的SCN生成器。
作为数据库内部的逻辑时钟,数据库事务依SCN而排序,oracle也依据SCN来实现一致性读(Read Consistency)等重要数据库功能。另外对于分布式事务(Distrbuted 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(Checkpoint SCN) resetlogs SCN等。
SCN的获取方式
可以通过如下几种方式获得数据库的当前或近似SCN。
从oracle9i开始。
可以使用dbms_flashback.get_system_change_number 来获得。
SQL > select dbms_flashback.get_system_change_number from dual;
get_system_change_number
----------------------------------
2982184
SCN的进一步说明
系统当前SCN并不是在任何的数据库操作发生时都会改变,SCN通常在事务提交或回滚时改变。在控制文件、数据文件头、数据块、日志文件头、日志文件change vector中都有SCN,但其作用各不相同。
(1)数据文件头重包含了该数据文件的Checkpoint SCN,表示该数据文件最近一次执行检查点操作时的SCN。
从控制文件的dump文件中,可以得到以下内容:
SQL > alter session set events ‘immediate trace name CONTROLF level 12’
会话已更改。
从控制文件的dump文件中,可以得到以下内容:
DATA FILE #1:
(name #4) /opt/oracle/oradata/conner/system01.dbf
creation size=32000 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:273 scn: 0x0000.0023aff1 11/22/2004 17:10:11
Stop scn: 0xffff.ffffffff 11/22/2004 16:58:49
Creation Checkpointed at scn: 0x0000.00000008 10/20/2004 20:59:35
thread:1 rba:(0x1.3.10)
对于每一个数据文件都包含一个这样的条目,记录该文件的检查点SCN的值以及检查点发生的时间,这里的checkpoint SCN,stop SCN以及checkpoint Cnt都是非常重要的数据结构,我们将会在下面检查点部分详细介绍。
同样可以通过命令转储数据文件头,观察其具体信息及检查点记录等:
SQL > alter session set events ‘immediate trace namefile_hdrs level 12’;
Session altered ;
SQL > @gettrcname
TRACE_FILE_NAME
----------------------------
/opt/oracle/admin/conner/udump/conner_ora_5862.trc
SQL > !
从跟踪文件中摘取SYSTEM表空间的记录作为参考:
DATA FILE #1:
(name #4) /opt/oracle/oradata/conner/system01.dbf
creation size=32000 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:319 scn: 0x0000.002e3016 12/03/2004 06:42:18
Stop scn: 0xffff.ffffffff 12/01/2004 23:37:33
Creation Checkpointed at scn: 0x0000.00000008 10/20/2004 20:59:35
thread:1 rba:(0x1.3.10)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
Offline scn: 0x0000.001cff67 prev_range: 0
Online Checkpointed at scn: 0x0000.001cff68 11/16/2004 14:10:35
thread:1 rba:(0x1.2.0)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
Hot Backup end marker scn: 0x0000.00000000
aux_file is NOT DEFINED
FILE HEADER:
Software vsn=153092096=0x9200000, Compatibility Vsn=134217728=0x8000000
Db ID=3152029224=0xbbe02628, Db Name='CONNER'
Activation ID=0=0x0
Control Seq=1093=0x445, File size=32000=0x7d00
File Number=1, Blksiz=8192, File Type=3 DATA
Tablespace #0 - SYSTEM rel_fn:1
Creation at scn: 0x0000.00000008 10/20/2004 20:59:35
Backup taken at scn: 0x0000.001aca21 11/14/2004 09:08:34 thread:1
reset logs count:0x20541edb scn: 0x0000.001cff68 recovered at 12/01/2004 23:07:30
status:0x4 root dba:0x004001a1 chkpt cnt: 319 ctl cnt:318
begin-hot-backup file size: 32000
Checkpointed at scn: 0x0000.002e3016 12/03/2004 06:42:18
thread:1 rba:(0x35.2.10)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
Backup Checkpointed at scn: 0x0000.001aca21 11/14/2004 09:08:34
thread:1 rba:(0xc6.4fff.10)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
External cache id: 0x0 0x0 0x0 0x0
Absolute fuzzy scn: 0x0000.00000000
Recovery fuzzy scn: 0x0000.00000000 01/01/1988 00:00:00
Terminal Recovery Stamp scn: 0x0000.00000000 01/01/1988 00:00:00
(2)日志文件头中包含了LOW SCN 和Next SCN。
Low SCN和Next SCN这两个SCN表示该日志文件包含有介于Low SCN到Next SCN的重做信息,对于current 的日志文件(当前正在被使用的redo logfile),其最终SCN不可知,所以Next SCN被置为无穷大,也就是ffffffff。
来看一下日志文件的情况:
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE#
FIRST_TIM
------- -------- ---------- ---------- ---------- --- -------- ------------- ---------
1 1 50 10485760 1 YES ACTIVE 2973017 02-DEC-04
2 1 51 10485760 1 NO CURRENT 2984378 02-DEC-04
3 1 49 10485760 1 YES INACTIVE 2966611 01-DEC-04
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
2984476
SQL> alter system switch logfile;
System altered.
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE#
FIRST_TIM
------- -------- ---------- ---------- ---------- --- -------- ------------- ---------
1 1 50 10485760 1 YES INACTIVE 2973017 02-DEC-04
2 1 51 10485760 1 YES INACTIVE 2984378 02-DEC-04
3 1 52 10485760 1 NO CURRENT 2984481 02-DEC-04
可以看到,SCN 2984476显然位于log group#为2的日志文件中,该日志文件包含了SCN自2984378至2984481的redo信息.oracle在进行恢复时,就需要根据低SCN和高SCN来确定需要的恢复信息位于哪一个日志或归档日志文件中。
如果通过控制文件转储,可以在控制文件中找到关于日志文件的信息:
SQL >ALTER SESSION SET EVENTS 'immediate trace name redohdr level 12';
Session altered;
LOG FILE #1:
(name #1) /opt/oracle/oradata/conner/redo01.log
Thread 1 redo log links: forward: 2 backward: 0
siz: 0x5000 seq: 0x00000011 hws: 0x2 bsz: 512 nab: 0x2 flg: 0x1 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.0023ac36
Low scn: 0x0000.0023afee 11/22/2004 17:10:06
Next scn: 0x0000.0023aff1 11/22/2004 17:10:11
LOG FILE #2:
(name #2) /opt/oracle/oradata/conner/redo02.log
Thread 1 redo log links: forward: 3 backward: 1
siz: 0x5000 seq: 0x00000012 hws: 0x2 bsz: 512 nab: 0x19 flg: 0x1 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.0023afee
Low scn: 0x0000.0023aff1 11/22/2004 17:10:11
Next scn: 0x0000.0023b01e 11/22/2004 17:10:54
LOG FILE #3:
(name #3) /opt/oracle/oradata/conner/redo03.log
Thread 1 redo log links: forward: 0 backward: 2
siz: 0x5000 seq: 0x00000013 hws: 0x1 bsz: 512 nab: 0xffffffff flg: 0x8 dup: 1
Archive links: fwrd: 0 back: 0 Prev scn: 0x0000.0023aff1
Low scn: 0x0000.0023b01e 11/22/2004 17:10:54
Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
同时注意到,log file3是当前的日志文件,该文件拥有的next scn 为无穷大。
同样,可以通过直接dump日志文件的方式来进行转储:
SQL >Select * from v$logfile;
Group# status type member
-----------------------------------------------------------------------------
1 ONLINE /opt/oracle/oradata/conner/redo01.log
2 ONLINE /opt/oracle/oradata/conner/redo02.log
3 ONLINE /opt/oracle/oradata/conner/redo03.log
SQL > alter system dump logfile ‘/opt/oracle/oradata/conner/redo01.log’
System altered.
在trace文件中,可以看到关于SCN的详细内容:
DUMP OF REDO FROM FILE '/opt/oracle/oradata/conner/redo01.log'
Opcodes *.*
DBA's: (file # 0, block # 0) thru (file # 65534, block # 4194303)
RBA's: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff
SCN's scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
Times: creation thru eternity
FILE HEADER:
Software vsn=153092096=0x9200000, Compatibility Vsn=153092096=0x9200000
Db ID=3152029224=0xbbe02628, Db Name='CONNER'
Activation ID=3154332244=0xbc034a54
Control Seq=1084=0x43c, File size=20480=0x5000
File Number=1, Blksiz=512, File Type=2 LOG
descrip:"Thread 0001, Seq# 0000000050, SCN 0x0000002d5d59-0x0000002d89ba"
thread: 1 nab: 0x15be seq: 0x00000032 hws: 0x2 eot: 0 dis: 0
reset logs count: 0x20541edb scn: 0x0000.001cff68
Low scn: 0x0000.002d5d59 12/02/2004 11:25:40
Next scn: 0x0000.002d89ba 12/02/2004 15:29:42
Enabled scn: 0x0000.001cff68 11/16/2004 14:10:35
Thread closed scn: 0x0000.002d5d59 12/02/2004 11:25:40
Log format vsn: 0x8000000 Disk cksum: 0xd79c Calc cksum: 0xd79c
Terminal Recovery Stamp scn: 0x0000.00000000 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: 0x0
直接从sys 用户dump出来的trace和 session转存储下来的日志是一样的。
这里不打算详细介绍具体命令的用法及更进一步的内容,因为对于一本书来说,这些内容还是太广阔了,在这里只希望给大家直观的认识,有兴趣的朋友可以由此开始进一步的探索。