Oracle SCN与检查点详解


1.SCN 的定义

SCN(System Change Number ),也就是通常所说的系统改变号,是数据库中非常重要的 一个数据结构 。

SCN 用以标识数据库在某个确切时刻提交的版本 。在事务提交时,它被赋予一个惟一的 标识事务的SCN 。SCN 同时被作为 Oracle数据库的内部时钟机制,可被看作逻辑时钟,每个 数据库都有一个全局的 SCN 生成器 。

作为数据库内部的逻辑时钟,数据库事务依 SCN 而排序,Oracle 也依据 SCN 来实现一致性读 (Read Consistency )等重要数据库功能 。另外对于分布式事务(Distributed 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 等 。

2.SCN 的获取方式

可以通过如下几种方式获得数据库的当前或近似 SCN 。

SQL> SELECT dbms_flashback.get_system_change_number FROM DUAL; 
GET_SYSTEM_CHANGE_NUMBER
------------------------
      6051905241299
SQL>

3.SCN 的进一步说明

系统当前SCN 并不是在任何的数据库操作发生时都会改变,SCN 通常在事务提交或回滚 时改变 。在控制文件、数据文件头、数据块、日志文件头、日志文件 change vector 中都有 SCN,但其作用各不相同 。

(1)数据文件头中包含了该数据文件的 Checkpoint SCN,表示该数据文件最近一次执行 检查点操作时的 SCN 。

对于每一个数据文件都包含一个这样的条目,记录该文件的检查点 SCN 的值以及检查点 发生的时间,这里的Checkpoint SCN 、Stop SCN以及 Checkpoint Cnt 都是非常重要的数据 结构.

4.检查点

许多文档把Checkpoint 描述得非常复杂,为我们正确理解检查点带来了障碍,结果现在 检查点变成了一个非常复杂的问题 。实际上,检查点只是一个数据库事件,它存在的根本意 义在于减少崩溃恢复(Crash Recovery )时间 。

当修改数据时,需要首先将数据读入内存中(Buffer Cache),修改数据的同时,Oracle 会记录重做信息(Redo)用于恢复 。因为有了重做信息的存在,Oracle 不需要在提交时立即 将变化的数据写回磁盘(立即写的效率会很低),重做(Redo)的存在也正是为了在数据库崩 溃之后,数据可以恢复 。

最常见的情况,数据库可能因为断电而 Crash,那么内存中修改过的、尚未写入文件的 数据将会丢失 。在下一次数据库启动之后,Oracle 可以通过重做日志(Redo)进行事务重演 (也就是进行前滚),将数据库恢复到崩溃之前的状态,然后数据库可以打开提供使用,之后 Oracle可以将未提交的事务进行回滚 。

在这个过程中,通常大家最关心的是数据库要经历多久才能打开 。也就是需要读取多少 重做日志才能完成前滚 。当然用户希望这个时间越短越好,Oracle 也正是通过各种手段在不 断优化这个过程,缩短恢复时间 。

检查点的存在就是为了缩短这个恢复时间 。

当检查点发生时(此时的SCN 被称为Checkpoint SCN ),Oracle会通知DBWR进程,把 修改过的数据,也就是此Checkpoint SCN之前的脏数据(Dirty Data)从Buffer Cache 写入磁盘,当写入完成之后,CKPT进程更新控制文件和数据文件头,记录检查点信息,标 识变更 。

Checkpoint SCN 可以从数据库中查询得到:

SQL> select file#,NAME,CHECKPOINT_CHANGE#,to_char(CHECKPOINT_TIME,'yyyy -mm-dd hh24:mi:ss') CPT from v$datafile; 
   FILE# NAME                                       CHECKPOINT_CHANGE# CPT
---------- -------------------------------------------------------------------------------- ------------------ --------------------
     1 /u01/app/oracle/oradata/orcl/system01.dbf                       6051905239995 2016 -05-05 04:14:32
     2 /u01/app/oracle/oradata/orcl/sysaux01.dbf                       6051905239995 2016 -05-05 04:14:32
     3 /u01/app/oracle/oradata/orcl/undotbs01.dbf                      6051905239995 2016 -05-05 04:14:32
     4 /u01/app/oracle/oradata/orcl/users01.dbf                       6051905239995 2016 -05-05 04:14:32
     5 /u01/app/oracle/oradata/orcl/example01.dbf                      6051905239995 2016 -05-05 04:14:32
     6 /u01/app/oracle/oradata/orcl/DEV_odi_user.dbf                     6051905239995 2016 -05-05 04:14:32
     7 /u01/app/oracle/oradata/orcl/apex_01.dbf                       6051905239995 2016 -05-05 04:14:32
     8 /u01/app/oracle/oradata/orcl/APEX_6121090681146232.dbf                6051905239995 2016 -05-05 04:14:32
8 rows selected

在检查点完成之后,此检查点之前修改过的数据都已经写回磁盘,重做日志文件中的相 应重做记录对于崩溃/实例恢复不再有用 。

检查点的频度对于数据库的恢复时间具有极大的影响, 如果检查点的频率高,那么恢复时需要应用的重做日志就相对得少,恢复时间就可以缩短 。 然而,需要注意的是,数据库内部操作的相关性极强,过于频繁的检查点同样会带来性能问 题,尤其是更新频繁的数据库 。所以数据库的优化是一个系统工程,不能草率 。

更进一步可以知道,如果Oracle 可以在性能允许的情况下,使得检查点的SCN 逐渐逼近 Redo的最新变更,那么最终可以获得一个最佳平衡点,使得 Oracle 可以最大化的减少恢复 时间 。

为了实现这个目标,Oracle 在不同版本中一直在改进检查点的算法 。

总结

以上就是本文关于Oracle SCN与检查点详解的全部内容,希望对大家有所帮助 。感兴趣的朋友可以参考:oracle 数据库启动阶段分析 、 Oracle EBS工具选项:关闭其他表单修改方法  、 oracle 虚拟专用数据库详细介绍   等 。有什么问题可以随时留言,小编会及时回复大家的 。