zoukankan      html  css  js  c++  java
  • oracle中scn(系统改变号)

    系统scn:                 select checkpoint_change# from v$database;

    文件scn:                 select name,checkpoint_change# from v$datafile;

    结束scn:                 select name,last_change# from v$datafile;

    数据文件头部scn:     select name,checkpoint_change# from v$datafile_header;

    系统scn、文件scn、结束scn,这三者是在控制文件中,数据文件头部scn在数据文件上。

         数据库正常运行,系统scn、文件scn、数据文件头部scn(也称为开始scn),这三者是相同的,而结束scn是空,即无穷大(因为正常运行,还未关闭啊),这是正常运行的情况,那么当正常关闭时,四者的scn号是相同的。假如发生非正常关闭,结束scn是空值,那么下次启动数据库,oracle发现结束scn是空值,就知道上次是非正常关闭,所以就要进行实例恢复了。实例恢复需要的是redo log,那么oracle是如何确定使用哪个redo log?以及确定之后又该从该redo log哪里进行恢复的呢?下面做个实验。。。

        当前数据库的系统scn号:

    这是redo log的一些信息:

          我们主要关注第一次改变编号和状态,我们可以看见,第3号日志组,序列号36的FIRST_CHANGE#和当前数据库的系统scn号一致,为什么呢,FIRST_CHANGE#又是什么呢?从查询结果我们可以看出,1号日志组是最旧的,2号次之,3号是最新的,这是从FIRST_CHANGE#可以看出来的,有FRIST就应该有NEXT啊,其实不难理解,下一个日志组的FIRST_CHANGE#其实就是这当前日志组的NEXT。所以例如1号日知组,FIRST_CHANGE#是1372964,NEXT是1395875。FIRST_CHANGE#的意义是该日志文件的第一条日志内容的scn号,NEXT就是该日志文件的最后一条内容的scn号了。那么如果此时数据库崩溃,数据文件的scn号是1398359,而3号日志文件的FIRST_CHANGE#也是1398359,且当3号日志组的状态是current,恢复就只要恢复3号日志组文件的内容就可以了,因为其他日志文件所记录的内容已写入到数据文件中。

          还有一种情况,如果三个日志组的状态是active、active、current,那么数据文件的scn号就会和比较旧的active的日志组的FIRST_CHANGE#一致,这时如果崩溃后恢复,那么三个日志组都会用到。

          结论:现在可以理解了,scn号的目的是为了保证数据库状态的一致性,而scn和redo log的FIRST_CHANGE#作用是,当实例恢复的时候,确定了该跑哪个日志组,才能将脏块重现在buffer cache中。而确定日志组后,又该从该日志组的哪条日志开始,就要从控制文件的LRBA中获取了(在我的上一个随笔检查点队列中有描述)。

  • 相关阅读:
    CSS基本
    Visual Basic相关图书推荐
    Docker相关图书推荐
    PASCAL相关图书推荐
    正则表达式相关图书推荐
    Go语言相关图书推荐
    F#相关图书推荐
    Ruby相关图书推荐
    PHP相关图书推荐
    Swift相关图书推荐
  • 原文地址:https://www.cnblogs.com/oraclelike/p/6155512.html
Copyright © 2011-2022 走看看