• Oracle SCN详解


    SCN号概述
    SCN是当Oracle数据库更新后,由DBMS自动维护去累积递增的一个数字。Oracle数据库中一共有4种SCN分别为

    系统检查点SCN: 系统检查点SCN位于控制文件中,当检查点进程启动时(ckpt),Oracle就把系统检查点的SCN存储到控制文件中。该SCN是全局范围的,当发生文件级别的SCN时,例如将表空间置于只读状态,则不会更新系统检查点SCN。  

    查询系统检查点SCN的命令如下

    SQL> select CHECKPOINT_CHANGE# from v$database;
    CHECKPOINT_CHANGE#
    ------------------
                590694

    数据文件scn:当ckpt进程启动时,包括全局范围的(比如日志切换)以及文件级别的检查点(将表空间置为只读、begin backup或将某个数据文件设置为offline等),这时会在控制文件中记录的scn。
    查询数据文件SCN的命令如下

    SQL> alter tablespace users read only;
    Tablespace altered.

    SQL> select file#,checkpoint_change# from v$datafile;
         FILE# CHECKPOINT_CHANGE#
    ---------- ------------------
             1             592277
             2             592277
             3             592277
             4             592291
             5             592277

    SQL> select checkpoint_change# from v$database;
    CHECKPOINT_CHANGE#
    ------------------
                592277
    可以看到4号文件也就是users表空间所属的文件scn值和其他文件不一致,且比系统检查点的scn要大。
    结束scn:每个数据文件都有一个结束scn,在数据库的正常运行中,只要数据文件在线且是可读写的,结束scn为null。否则则存在具体的scn值。结束scn也记录在控制文件中。

    SQL>select TABLESPACE_NAME,STATUS from dba_tablespaces
    TABLESPACE_NAME   STATUS
    ----------------- ---------------------------
    SYSTEM            ONLINE
    UNDOTBS1          ONLINE
    SYSAUX            ONLINE
    TEMP              ONLINE
    USERS             READ ONLY
    EXAMPLE           ONLINE

    SQL> select file#,LAST_CHANGE# from  v$datafile;
         FILE# LAST_CHANGE#
    ---------- ------------
             1
             2
             3
             4       592291
             5
    可以看到除了users表空间的结束scn不为空,其他数据文件的结束scn为空。

    将数据库至于mount状态,由于该状态下所有的数据文件都不可写,故mount状态下所有的数据文件都具有结束scn。

    SQL> shutdown immediate;
    SQL> startup mount;

    SQL> select file#,last_change# from v$datafile;
         FILE# LAST_CHANGE#
    ---------- ------------
             1       592608
             2       592608
             3       592608
             4       592291
             5       592608

    数据文件头scn:不同于上述的SCN数据文件开始scn记录在每个数据文件中。当发生系统及文件级别的检查点后,不仅将这时的SCN号记录在控制文件中,同样也记录在数据文件中。

    查询数据文件头SCN的命令如下

    SQL> select file#,CHECKPOINT_CHANGE# from v$datafile_header;
         FILE# CHECKPOINT_CHANGE#
    ---------- ------------------
             1             592608
             2             592608
             3             592608
             4             592291
             5             592608
    SCN的机制

    数据库运行时的SCN

    我们先看下oracle事务中的数据变化是如何写入数据文件的:

    1、 事务开始;

    2、 在buffer cache中找到需要的数据块,如果没有找到,则从数据文件中载入buffer cache中;

    3、 事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;

    4、 事务提交,LGWR进程将log buffer中的“脏数据”写入redo log file中;

    5、 当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWr进程则负责将Buffer Cache中的脏数据写入到数据文件中。

    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。
    SQL> select recid,sequence#,first_change#,next_change# from v$log_history ;             
         RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
    ---------- ---------- ------------- ------------
             1          1        446075       474154
             2          2        474154       497385
             3          3        497385       516087
             4          4        516087       540659
             5          5        540659       564897
             6          6        564897       564903
             7          7        564903       565320
             8          8        565320       565704
             9          9        565704       565715
            10         10      565715       567343
            11         11      567343       587705
    查看currnet redolog中的high scn
    SQL>select vf.member,v.status,v.first_change# from v$logfile vf,v$log v
      2      where vf.group#=v.group#
      3*   and v.status='CURRENT'

    MEMBER                                                              STATUS             FIRST_CHANGE#
    ------------------------------------------------------------    --------------           -------------
    /u01/app/oradata/orcl/redo02.log                             CURRENT         587705
     
    SQL>alter system dump logfile ' /u01/app/oradata/orcl/redo02.log';
     
    SQL> show parameter user_dump
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    user_dump_dest                       string      /home/oracle/admin/c001/udump

    打开转储出来的文件,可以看到

    DUMP OF REDO FROM FILE '/u01/app/oradata/orcl/redo02.log'
     Opcodes *.*
     RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff
     SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
     Times: creation thru eternity
     FILE HEADER:
            Compatibility Vsn = 169869568=0xa200100
            Db ID=1269936864=0x4bb1b2e0, Db Name='ORCL'
            Activation ID=1269912032=0x4bb151e0
            Control Seq=696=0x2b8, File size=102400=0x19000
            File Number=2, Blksiz=512, File Type=2 LOG
     descrip:"Thread 0001, Seq# 0000000012, SCN 0x00000008f7b9-0xffffffffffff"
     thread: 1 nab: 0x34f6 seq: 0x0000000c hws: 0x9 eot: 1 dis: 0
     resetlogs count: 0x2c3c676f scn: 0x0000.0006ce7b (446075)
     resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
     prev resetlogs count: 0x2184ef74 scn: 0x0000.00000001 (1)
     prev resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
     Low  scn: 0x0000.0008f7b9 (587705) 04/20/2011 09:35:56
     Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
     Enabled scn: 0x0000.0006ce7b (446075) 02/03/2011 18:29:03
     Thread closed scn: 0x0000.00090ae0 (592608) 04/20/2011 15:29:05
     Disk cksum: 0x30ee Calc cksum: 0x30ee
     Terminal recovery stop scn: 0x0000.00000000
     Terminal recovery  01/01/1988 00:00:00
     Most recent redo scn: 0x0000.00000000
     Largest LWN: 1920 blocks
     End-of-redo stream : No
     Unprotected mode
     Miscellaneous flags: 0x0
     Thread internal enable indicator: thr: 0, seq: 0 scn: 0x0000.00000000

    redo log中当前系统的SCN记录当前最新的数据库scn值可通过如下命令查看

    SQL> select dbms_flashback.get_system_change_number from dual;
    GET_SYSTEM_CHANGE_NUMBER
    ------------------------
                      594373
    如果需要进行实例恢复,则需要恢复的记录为587705至594373中redo log中的记录。

    日志切换或者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#可以查询)、每个数据文件对应的Datafile Checkpoint(通过视图v$datafile的字段checkpoint_change#可以查询)也更新为Next SCN。但是,如果该数据文件所在的表空间被设置为read-only时,数据文件的Start SCN和控制文件中Datafile Checkpoint SCN都不会被更新。

    心跳
    在Oracle中有一个事件叫Heartbeat,这个词在很多地方被提及,并且有着不同的含义(比如RAC中),我们这里要讨论的是CKPT的Heartbeat机制。
    Oracle通过CKPT进程每3秒将Heartbeat写入控制文件,以减少故障时的恢复时间

    数据库正常关闭启动

    数据库正常关闭时,系统会执行一个完全检查点动作,并用该检查点时的SCN号更新上述4个SCN号,这时所有数据文件的终止SCN号会设置为数据文件头的那个启动SCN(除了离线和只读的数据文件)

    数据库重新启动时,Oracle将数据文件头中的启动SCN与数据文件检查点SCN比较,如果这两个值匹配,Oracle接下来再比较数据文件头中的SCN和控制文件中数据文件的终止SCN,如果这个值也匹配,就意味着所有数据块已经提交,因此数据库不需要进行恢复,此时数据库直接打开。当所有的数据文件都打开之后,在线且可读写的数据文件终止SCN再次被设置为NULL,表示数据文件已经打开并能够正常使用了。有些表空间是只读的,这时控制文件中的系统检查点SCN号会不断增长,而数据文件SCN号和文件头中的启动SCN(会停止更新直到表空间又设置为可读写),显然这时系统检查点SCN号会大于数据文件SCN和文件头启动SCN。

    数据库非正常关闭
    数据库非正常关闭 ( 或称为实例崩溃 ) 时,终止 SCN 不会被设置,依然为 NULL ,这可以通过把数据库启动至 mount 状态查询出来。 这样重新启动时,SMON进程 会执行实例恢复工作,即先执行前滚、回滚操作,再把数据库打开。

    数据文件介质故障

    出现介质故障时,数据文件检查点SCN及系统检查点SCN比文件头启动SCN大。系统发生介质故障时,数据文件被以前的备份代替,控制文件中的数据文件检查点SCN肯定比文件头中的启动SCN要大,这样Oracle就知道要对这个文件进行介质 恢复

    控制文件介质故障

    系统检查点SCN及数据文件SCN比数据文件头启动SCN小:
    在数据库恢复时,控制文件可能不是最新的,即把一个较早的控制文件还原为当前的控制文件,然后再执行恢复操作,这时控制文件中的系统检查点SCN和数据文件SCN可能比文件头的启动SCN小。这时恢复数据库要用下面命令:recover database using Backup Controlfile或其他的恢复语句。

    备份时的实例崩溃

    当执行begin backup时实例崩溃:控制文件中的数据文件检查点SCN号和数据文件头部检查点SCN号相同,但是每个可读写的在线数据文件之间检查点SCN号不同,那么要求介质恢复,例如发出begin backup命令后就会出现这种情况,需要通过end backup命令好才可以打开数据库。

    转载:http://czmmiao.iteye.com/blog/1010267

  • 相关阅读:
    Fruit Ninja(随机数rand())
    C. A Mist of Florescence ----- Codeforces Round #487 (Div. 2)
    给力的移动 FZU
    FZU 2254 英语考试 (最小生成树)
    6486: An Ordinary Game(规律)
    HDU 1114: Piggy-Bank
    HDU 5916: Harmonic Value Description
    1072 威佐夫游戏
    1069 Nim游戏
    1066 Bash游戏
  • 原文地址:https://www.cnblogs.com/future2012lg/p/3115720.html
Copyright © 2020-2023  润新知