oracle的SCN

oracle的SCN号的几点说明:

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中的脏数据写入到数据文件中。


点滴总结:


1,在control file,redo log,data file中都存在SCN值;
2,数据库open时,检查control file中记录的SCN值与数据文件,redo log文件是否一致,如果是,数据库打开,否则,提示错误;假如数据文件SCN值小于control file中的SCN值则提示该数据文件需要介质恢复;
3,redo log 中存在低SCN,高SCN值两种,当前的redo log文件的高SCN值为无穷大;日志发生切换时,高SCN值更新为系统当前SCN值,新日志文件低SCN值为前日志文件高SCN值加1,高SCN值仍然为去穷大;数据库发生变化,则写redo log文件,同时SCN值会加1。
4,检查点发生时,CKPT更新数据文件头。


2. 常见的十分重要的SCN
1) 控制文件中的有三种SCN:系统SCN、数据文件SCN、数据文件结束SCN。
2) 数据文件中的SCN:数据文件头部的SCN,叫start SCN,也叫启动SCN。
3) redo logfile中的SCN:每一条日志记录有一个SCN,
                       每一个日志文件有一个first scn和一个next scn.
4) 数据块中的SCN:数据块头部ITL事务槽中有SCN(在跑日志时,会对ITL中的SCN和日志文件中的SCN进行比较,如果ITL中的SCN大一些,那么会进行空跑日志,如果ITL中的SCN小一些,则实际修改数据块.
5) 回滚段事务表中也有SCN。

系统SCN
当一个检查点动作完成后,Oracle就把系统检查点的SCN存储到控制文件中。
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------------------
            924192

数据文件SCN
当一个检查点动作完成后,Oracle就把每个数据文件的scn单独存放在控制文件中。
SQL> select name,checkpoint_change# from v$datafile;
NAME                                                                       CHECKPOINT_CHANGE#
--------------------------------------------------        -------------------------
/u01/app/oracle/oradata/jiagulun/system01.dbf                 924192
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf                924192
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf                  924192
/u01/app/oracle/oradata/jiagulun/users01.dbf                    924192
/u01/app/oracle/oradata/jiagulun/example01.dbf                924192

文件结束SCN
当数据库正常关闭时,会将文件结束SCN存放在控制文件中。而在数据库正常运行时,控制文件中的文件结束SCN为空,当数据库非正常关闭时,那么文件结束SCN的值会为空,所以在数据库启动时,会根据文件结束SCN来判断是否要进行实例崩溃恢复

SQL> select name,last_change# from v$datafile;
NAME                                                                       LAST_CHANGE#
--------------------------------------------------         ------------
/u01/app/oracle/oradata/jiagulun/system01.dbf                 null
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf                null
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf                  null
/u01/app/oracle/oradata/jiagulun/users01.dbf                    null
/u01/app/oracle/oradata/jiagulun/example01.dbf                null

数据文件头部SCN
在每一个数据文件的头部还有一个开始SCN
SQL> select name,checkpoint_change# from v$datafile_header;
NAME                                                                      CHECKPOINT_CHANGE#
----------------------------------------------             ------------------
/u01/app/oracle/oradata/jiagulun/system01.dbf                  924192
/u01/app/oracle/oradata/jiagulun/undotbs01.dbf                 924192
/u01/app/oracle/oradata/jiagulun/sysaux01.dbf                   924192
/u01/app/oracle/oradata/jiagulun/users01.dbf                     924192
/u01/app/oracle/oradata/jiagulun/example01.dbf                 924192

开始SCN也叫启动scn,因为它用于在数据库实例启动时,检查是否需要执行数据库恢复。在数据库启动时,如果在控制文件中的文件SCN和数据文件头部的SCN不一致,那么就要进行恢复。可能会用到归档日志。而数据库实例崩溃恢复只会用到ACTIVE和CURRENT中的日志,因为INACTIVE对应的脏数据块已经写入到了磁盘中。

日志文件中的SCN
redo logfile中的每一条日志记录有一个SCN,
              每一个日志文件的头部有两个SCN:first SCNnext SCN.
first SCN即该日志文件中第一条日志记录中的SCN,而next SCN是 该日志文件的最后一条日志文件的SCN,也就是下一个日志文件的第一条日志记录中的SCN,也就是说下一个日志文件的first SCN等于上一个日志文件的next SCN. 所以first SCN和next SCN记录了该日志文件的日志记录的范围。这样通过每一个日志文件头部的first SCN和next SCN可以将所有的日志文件串联起来,当成一个整体的日志文件。sybase的日志文件好像就是一个整体的日志文件。而Oracle却巧妙地通过日志文件头部的first SCN和next SCN将所有的日志文件连了起来
SQL> select recid,sequence#,first_change#,next_change# from v$log_history where rownum<6;

     RECID  SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
---------- ----------- ---------------   ------------
         1          1         446075               473470
         2          2         473470               480715
         3          3         480715               498876
         4          4         498876               520938
         5          5         520938               555508
从上面的结果我们可以清楚的看到first SCN和next SCN是串联起来的。

SQL> select * from v$log;
 GROUP# THREAD# SEQUENCE# BYTES    MEMBERS ARC  STATUS    FIRST_CHANGE# 
-------- --------- ----------  --------- ---------  ---  ---------  -----------------
         1          1         26       52428800          1    NO   CURRENT             924192 
         2          1         24       52428800          1    YES  INACTIVE            906864 
         3          1         25       52428800          1    YES  INACTIVE            907884 

我们知道日志文件分为CURRENT, ACTIVE, INACTIVE三者,CURRENT表示当前正在使用的日志文件,ACTIVE表示日志文件中对应的脏块还没有写到磁盘中,而INACTIVE则表示日志文件中对应的所有脏块都写到了磁盘中。

系统SCN、文件SCN、数据文件头部SCN三者的值等于ACTIVE, CURRENT中最老的一个日志文件的头部的first SCN. 这三个值只有在日志文件由ACTIVE变为INACTIVE时,才会更新。因为INACTIVE日志对应的脏块都写入到了磁盘中,不需要恢复。而增量checkpoint操作只是将checkpoint-Q中的最老的脏块对应的日志的地址即LRBA写到控制文件中,它并不会修改SCN. 所以在恢复时,可以根据系统SCN与日志文件头部的first SCN比较就可以找到要使用那个日志文件,然后再向新的日志方向寻找LRBA地址对应的具体的那一条日志记录。然后从LRBA到On disk RBA进行前滚,前滚之后在利用undo进行回滚。

日志记录中的SCN与commit的关系

当我们执行 commit 时,LGWR会将log buffer写入redo logfile,同时也会将对应的SCN同步写入到redo logfile内(wait-until-completed)。因此当你commit transaction时,在成功返回之前,LGWR必须先完整的完成上述行为之后,否则你是看不到提交成功的返回的。
可以查询目前系统最新的SCN 
SQL> select dbms_flashback.get_system_change_number scn from dual;
       SCN
----------
    944406

可以理解,这里返回的SCN,也是目前redo logfile最新的SCN纪录。因为commit后才会有SCN,而一旦commit就会立刻写入redo logfile中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值