`
xitonga
  • 浏览: 587025 次
文章分类
社区版块
存档分类
最新评论

【转】Oracle的SCN剖析

 
阅读更多

本文对oracle的SCN 进行了非常细致的剖析,可谓是挖到了SCN的祖坟,非常值得学习。

转自:http://blog.chinaunix.net/uid-25909722-id-3376457.html

1. SCN的本质

SCN即System Change Number。它的本质是一个时间点,可以精确到纳秒。而个人电脑的微处理器执行一道指令(如将两数相加)约需2至4纳秒。所以这个时间点已经是十分的精确了。Oracle在内部用这个时间点来标识某个操作的完成当Oracle数据库某个操作后,SCN由DBMS自动递增。SCN被用来保证数据库的一致性以及数据恢复等。SCN几乎存在于Oracle系统的任何地方。

SQL> select dbms_flashback.get_system_change_number scn,scn_to_timestamp(dbms_flashback.get_system_change_number) timestamp from dual;

SCNTIMESTAMP
------------- ----------------------------------
-------
931316 17-OCT-12 03.11.56.000000000 PM

SCN的最大值:
SQL> select ((((((
to_char(sysdate,'YYYY')-1988
)*12+
to_char(sysdate,'mm')-1
)*31+
to_char(sysdate,'dd')-1
)*24+
to_char(sysdate,'hh24')
)*60+
to_char(sysdate,'mi')
)*60+
to_char(sysdate,'ss')
)*to_number('ffff','xxxxxxxx')/4 scn from dual;
SCN
----------
1.3057E+13
这样看来SCN的最大的值,随着时间的推移会逐渐的增大。

http://www.eygle.com/archives/2006/01/how_big_scn_can_be.html

1.oracle 为了防止scn的异常增长所以限制每一秒钟允许最多产生 256*256/4 个scn
2.oracle 内部使用了一个4G范围的数据来表示01/01/1988 00:00:00 ~ 08/18/2121 06:28:15 这段时间.它的算法简单,说来就是每个月都是用的31天来表示时间,每增加1秒,这个数值就增加1. 可以从redo file dump ,control file dump,datafile head dump 观察到这个值.

当前系统可能的最大scn 就是上面两个值的乘积:1988/01/01 00:00:00到当前时间的秒数乘以256*256/4
256=power(2,8),所以256*256=power(2,16)=0xffff=to_number('ffff','xxxxxxxx')

我们看一下 LRBA 对应的日志中的SCN:
SQL> select CPDRT,CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low RBA",
CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk RBA",
CPODS,CPODT,CPHBT from X$KCCCP;

CPDRT Low RBA On disk RBACPODSCPODT CPHBT
-------- ---------- ------------ --------- --------------------- -------------
62 26.80884.0 26.81039.0 934874 10/17/2012 15:53:58 795883580
0 0.0.0 0.0.0 0 0

0 0.0.0 0.0.0 0 0
0 0.0.0 0.0.0 0 0
0 0.0.0 0.0.0 0 0
0 0.0.0 0.0.0 0 0
0 0.0.0 0.0.0 0 0
0 0.0.0 0.0.0 0 0

8 rows selected.

CPDRT:是检查点队列中的脏块数目(dirt).
CPODS:是On Disk rba的SCN,表示日志文件中最新的那条日志记录中的SCN。
CPODT:是On Disk rba的Timestamp.
CPHBT:心跳(heart beat).

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> selectcheckpoint_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 446075473470
2 2473470480715
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中。

CHECKPOINT和SCN的关联:
完全Checkpoint 发生的目的就是要把存储在buffer内的已提交数据写回disk,否则一旦发生crash,需要进行recovery时,就必须花很多时间进行recovery,这样在商业应用上是很浪费时间和没有效率的。

当commit一笔交易时,只会立刻将redo buffer写入redo logfile内,但是并不会马上将该update后的block(dirty block)同步写回disk datafile中,这是为了减少过多disk IO,所以采取batch方式写入。

When a checkpoint occurs. Oracle must update the headers of all datafiles to record the details of the checkpoint.This is done by the CKPT process. The CKPT process does not write blocks to disk; DBWn always performs that work.

在shutdown normal or shutdown immediate下,也就是所谓的clean shutdown, checkpoint也会自动触发。当发生完全checkpoint时,会把SCN写到四个地方去。三个地方在control file 内,一个在各个datafile的header。

在数据库运行期间的scn值:
在数据库打开并运行之后,控制文件中的系统检查点、控制文件中的数据文件检查点scn和每个数据文件头中的启动scn都是相同的。控制文件中的每个数据文件的终止scn都为null.

在安全关闭数据库的过程中,系统会执行一个检查点动作,这时所有数据文件的终止scn都会设置成数据文件头中的那个启动scn的值。在数据库重新启动的时候,Oracle将文件头中的那个启动scn与数据库文件检查点scn进行比较,如果这两个值相互匹配,oracle接下来还要比较数据文件头中的启动scn和控制文件中数据文件的终止scn。如果这两个值也一致,就意味着所有数据块多已经提交,所有对数据库的修改都没有在关闭数据库的过程中丢失,因此这次启动数据库的过程也不需要任何恢复操作,此时数据库就可以打开了。当所有的数据库都打开之后,存储在控制文件中的数据文件终止scn的值再次被更改为null这表示数据文件已经打开并能够正常使用了。

分享到:
评论

相关推荐

    oracle scn概念解析

    oracle scn分析及概念解释,及各种scn的查询sql语句

    Oracle中用LogMiner分析重做及归档日志

    LogMiner是集成在Oracle8i/Oracle9i数据库产品中的日志分析工具,通过该工具可以分析重做日志和归档日志中的所有事务变化,并能准确地确定各种DML和DDL操作的具体时间和SCN值。对重做日志和归档日志进行分析的目 的...

    Oracle11g体系结构深入剖析和运维管理(四)

    资源名称:Oracle 11g体系结构深入剖析和运维管理(四)资源目录:【】28_存储结构_段区块【】29_检查点队列(checkpointqueue)【】30_实例崩溃恢复原理剖析【】31_系统改变号(SCN)详解【】32_事务概述【】33_事务ACID...

    分析Oracle8i/9i的重做日志和归档日志

    LogMiner是集成在Oracle8i/Oracle9i数据库产品中的日志分析工具,通过该工具可以分析重做日志和归档日志中的所有事务变化,并能准确地确定各种DML和DDL操作的具体时间和SCN值。文中以Oracle8i(8.1.5)for Windows ...

    Oracle DBA实战攻略

    本书是目前Oracle数据库运维领域不可多得的一本著作,也是为数不多的既有大量实践应用案例又包含实战方法论的著作。作者根据其多年的运维诊断经验,从数据库如何创建开始,循序渐进地介绍了数据库的启动关闭过程,...

    深入解析Oracle.DBA入门进阶与诊断案例

    针对数据库的启动和关闭、控制文件与数据库初始化、参数及参数文件、数据字典、内存管理、Buffer Cache与Shared Pool原理、重做、回滚与撤销、等待事件、性能诊断与SQL优化等几大Oracle热点主题,本书从基础知识入手...

    Oracle的回滚段存储内容分析

    在执行update操作之后,oracle后台进程会首先将修改前的内容(包括数据块中其他记录内容)以及scn,块信息等写入回滚段中,但这里写的时候不仅仅只是简单的块复制,而是将原来的数据块顺序写入回滚段的数据块。...

    相克军 ORACLE 讲座 深度剖析UNDO段 笔记

    本文用图形化直观的方式形像的描述出ORACLE UNDO段里的事务槽、SCN号、事务控制、事务锁的真正原理。将深奥难懂的锁、事务、一致性形像的展示出来。本文还借供了大量的查询、优化UNDO段相关的SQL语句。非常有价值一...

    深入解析OracleDBA入门进阶与诊断案例 3/4

     本书给出了大量取自实际工作现场的实例,在分析实例的过程中,兼顾深度与广度,不仅对实际问题的现象、产生原因和相关的原理进行了深入浅出的讲解,更主要的是,结合实际应用环境,提供了一系列解决问题的思路和...

    深入解析OracleDBA入门进阶与诊断案例 2/4

     本书给出了大量取自实际工作现场的实例,在分析实例的过程中,兼顾深度与广度,不仅对实际问题的现象、产生原因和相关的原理进行了深入浅出的讲解,更主要的是,结合实际应用环境,提供了一系列解决问题的思路和...

    深入解析OracleDBA入门进阶与诊断案例 4/4

     本书给出了大量取自实际工作现场的实例,在分析实例的过程中,兼顾深度与广度,不仅对实际问题的现象、产生原因和相关的原理进行了深入浅出的讲解,更主要的是,结合实际应用环境,提供了一系列解决问题的思路和...

    如何使用log miner分析oracle日志

    当我们不小心误操作致使数据库数据丢失、改变时, 需要对数据库对象做基于时间点的恢复,找到我们需要的数据,这个时间点不能认为精确确定,我们可以通过对oracle日志进行分析,而获得无操作的精确时间点。...

    Oracle LogMiner的使用实例代码

    LogMiner 是Oracle公司从产品8i以后提供的一个实际非常有用的分析工具,使用该工具可以轻松获得Oracle 重做日志文件(归档日志文件)中的具体内容,LogMiner分析工具实际上是由一组PL/SQL包和一些动态视图组成,它...

    浅谈LogMiner的使用方法

    Logminer是每个Dba都应熟悉的工具,当一天由于用户的误操作你需要做不完全的恢复时,由于你无法确定这个操作是哪个时间做的,所以...2、它只能在Oracle8i及以后的版本中使用,不过它可以分析Oracle8的日志。 3、Oracle8

Global site tag (gtag.js) - Google Analytics