天天看点

SCN基础

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转存储下来的日志是一样的。

   这里不打算详细介绍具体命令的用法及更进一步的内容,因为对于一本书来说,这些内容还是太广阔了,在这里只希望给大家直观的认识,有兴趣的朋友可以由此开始进一步的探索。