检查点SCN在事务发生后以及发生检查点和归档操作后的变化

1、事务开始;

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

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

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

5、当发生 checkpointCKPT 进程更新所有数据文件的文件头中的信息,DBWn 进程则

负责将 Buffer Cache 中的脏数据写入到数据文件中。

经过上述 5 个步骤,事务中的数据变化最终被写入到数据文件中。但是,一旦在上述中

间环节时,数据库意外宕机了,在重新启动时如何知道哪些数据已经写入数据文件、哪些没

有写呢(同样,在 DGstreams 中也存在类似疑问:redo log 中哪些是上一次同步已经复制过

的数据、哪些没有)?SCN 机制就能比较完善的解决上述问题。SCN 是一个数字,确切的说

是一个只会增加、不会减少的数字。正是它这种只会增加的特性确保了 Oracle 知道哪些应该

被恢复、哪些应该被复制。

在一个事务提交后(上述第四个步骤),会在 redo log 中存在一条 redo 记录,同时,系

统为其提供一个最新的 SCN(通过函数 dbms_flashback.get_system_change_number 可以知道

当前的最新 SCN),记录在该条记录中。如果该条记录是在 redo log 被清空(日志满做切换

时或发生 checkpoint 时,所有变化日志已经被写入数据文件中),则其 SCN 被记录为 redo log

 low SCN。以后在日志再次被清空前写入的 redo 记录中 SCN 则成为 Next SCN

当日志切换(写满自动切换)或发生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 都不会被更新。


--以下操作是为了验证上述理论:

begin for i in 1..5 loop


insert into test.t3 values(i);

end loop;

commit;

end;

/

 

begin for i in 11..101 loop

insert into test.t3 values(i);

end loop;

commit;

end;

/

 

--下面是用到的语句清单

insert into test.t3 values(109);

select checkpoint_change#,current_scn from v$database;

commit;

insert into test.t3 values(110);

select checkpoint_change#,current_scn from v$database;

commit;

select checkpoint_change# from v$datafile;

select checkpoint_change# from v$datafile_header;

select checkpoint_change#,current_scn from v$database;

--发生一次归档,查看检查点SCN的变化

alter system archive log current;


select checkpoint_change#,current_scn from v$database;

select * from v$log;
--发生一次检查点,查看检查点SCN的变化

alter system checkpoint;

select checkpoint_change# from v$datafile;

select checkpoint_change# from v$datafile_header;

select checkpoint_change#,current_scn from v$database;

select * from v$log;

select sequence#,first_change#,next_change# from v$log_history;

--下面是上面脚本的实际操作过程

SYS@PROD>insert into test.t3 values(109);

 

1 row created.

 

select checkpoint_change#,current_scn from v$database;

 

CHECKPOINT_CHANGE# CURRENT_SCN

------------------ -----------

            747809      747844

 

SYS@PROD>commit;

 

Commit complete.

 

SYS@PROD>insert into test.t3 values(110);

 

1 row created.

 

SYS@PROD>select checkpoint_change#,current_scn from v$database;

 

CHECKPOINT_CHANGE# CURRENT_SCN

------------------ -----------

            747809      747847

 

SYS@PROD>commit;

 

Commit complete.

 

SYS@PROD>select checkpoint_change# from v$datafile;

 

CHECKPOINT_CHANGE#

------------------

            747809

            747809

            747809

            747809

            747809

            747809

            747809

            747809

            747809

 

9 rows selected.

 

SYS@PROD>select checkpoint_change# from v$datafile_header;

 

CHECKPOINT_CHANGE#

------------------

            747809

            747809

            747809

            747809

            747809

            747809

            747809

            747809

            747809

 

9 rows selected.

 
--发生归档,之后查看检查点的变化

SYS@PROD>alter system archive log current;

 

CHECKPOINT_CHANGE# CURRENT_SCN

------------------ -----------

            747809      747850

 

SYS@PROD>alter system archive log current;

select checkpoint_change#,current_scn from v$database;

 

System altered.

 

SYS@PROD>select checkpoint_change#,current_scn from v$database;

CHECKPOINT_CHANGE# CURRENT_SCN

------------------ -----------

            747809      747854

 --上面的检查点SCN没有变化,原因是设备IO不繁忙,因此要等一会儿才会更新三个检查点SCN,幽灵一篇文章专门论证这一点

SYS@PROD>select * from v$log;

 

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIV

---------- ---------- ---------- ---------- ---------- ------

STATUS                           FIRST_CHANGE# FIRST_TIME

-------------------------------- ------------- ------------

         1          1         31  104857600          4 NO

CURRENT                                 747853 31-JAN-14 –此处的747853为之前group3日志组归档时的当时系统SCN,作为group3日志组的HIGH SCN,也作为该当前日志的LOW SCN

 

         2          1         29  104857600          4 YES

INACTIVE                                747763 31-JAN-14

 

         3          1         30  104857600          4 YES

ACTIVE                                  747801 31-JAN-14

 

 --发生一次检查点,查看检查点SCN的变化

SYS@PROD>alter system checkpoint;

 

System altered.

--发起checkpoint后,控制文件中的Datafile Checkpoint SCN被同步为当时发起checkpoint时的系统SCN

SYS@PROD>select checkpoint_change# from v$datafile;

--证明

CHECKPOINT_CHANGE#

------------------

            747855

            747855

            747855

            747855

            747855

            747855

            747855

            747855

            747855

 

9 rows selected.

--发起checkpoint后,数据文件中的Start SCN被同步为当时发起checkpoint时的系统SCN

SYS@PROD>select checkpoint_change# from v$datafile_header;

--发起checkpoint后,控制文件中的Datafile Checkpoint SCN被同步为当时系统SCN

CHECKPOINT_CHANGE#

------------------

            747855

            747855

            747855

            747855

            747855

            747855

            747855

            747855

            747855

 

9 rows selected.

--发起checkpoint后,控制文件中的System Checkpoint SCN被同步为当时发起checkpoint时的系统SCN

SYS@PROD>select checkpoint_change#,current_scn from v$database;

 

CHECKPOINT_CHANGE# CURRENT_SCN

------------------ -----------

            747855      747856

 

SYS@PROD>select * from v$log;

 

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIV

---------- ---------- ---------- ---------- ---------- ------

STATUS                           FIRST_CHANGE# FIRST_TIME

-------------------------------- ------------- ------------

         1          1         31  104857600          4 NO

CURRENT                                 747853 31-JAN-14

 

         2          1         29  104857600          4 YES

INACTIVE                                747763 31-JAN-14

 

         3          1         30  104857600          4 YES

INACTIVE                                747801 31-JAN-14

 


请使用浏览器的分享功能分享到微信等