在网上经常看到有人提到全局检查点,也就是完全检查点。所谓完全检查点会将数据缓冲区里面所有的脏数据块写入相应的数据文件中,并且同步数据文件头和控制文件,保证数据库的一致。其实对于全局检查点,还有文件检查点,也就是CKPT进程只是刷新部分文件在数据缓冲区里面的所有脏数据块写入到对应的数据文件中,同步更新数据文件头和控制文件,以保证数据库的一致。
下面介绍的就是就是会触发文件检查点的让表空间offline。
-----准备数据
SQL> create tablespace test1
2 logging
3 datafile 'D:\APP\ASUS\ORADATA\TEST\TEST01.DBF' SIZE 10M REUSE;
表空间已创建。
SQL> create table test1 tablespace test1 as
2 select * from dba_tablespaces;
表已创建。
查看表空间在离线前,对应数据文件的checkpoint_change#以及last_change#。其中文件6是表空间test1对应数据文件,其checkpoint_change#为2127520,而last_change#为NULL。而之所以该文件的chekcpoint_change#跟其他数据文件不一样,是因为该表空间是刚刚建立的,并没有进行完全检查点的缘故。
-----查看表空间在离线前,对应数据文件的checkpoint_change#以及last_change#
SQL> select file#,checkpoint_change#,last_change# from v$datafile;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 2124722
2 2124722
3 2124722
4 2124722
5 2124722
6 2127520
已选择6行。
接着,我们把新建立的这个表空间离线,其实我们会发现,文件检查点会刷新相应高速缓冲区中的脏数据块到物理文件,更新了控制文件中对应数据文件中的checkpoint_change#为2130656和last_change#为2130656【也就是,该表空间的数据离线前的状态标识时钟】。而数据文件的文件头则被更新为0,但是v$database中的checkpoint_change#并没有发生变化。
SQL> alter tablespace test1 offline normal;
表空间已更改。
SQL> select file#,checkpoint_change#,last_change# from v$datafile;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 2124722
2 2124722
3 2124722
4 2124722
5 2124722
6 2130656 2130656
已选择6行。
SQL> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 2124722
2 2124722
3 2124722
4 2124722
5 2124722
6 0
已选择6行。
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
2124722
然后,我们试着进行一次完全检查点操作,我们会发现v$database中的checkpoint_change#发生了变化,同时v$datafile、v$datafile_header中的checkpoint_change#变成跟v$database一样的值,除了处于离线状态的数据文件6没有发生变化。这说明,全量检查点的作用对象不包括离线的数据文件。
SQL> alter system checkpoint;
系统已更改。
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
2131052
SQL> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 2131052
2 2131052
3 2131052
4 2131052
5 2131052
6 0
已选择6行。
SQL> select file#,checkpoint_change#,last_change# from v$datafile;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 2131052
2 2131052
3 2131052
4 2131052
5 2131052
6 2130656 2130656
已选择6行。
最后,我们要做的是把离线状态下的表空间重新在线。我们发现该操作也触发了局部的检查点。原来处于离线状态的数据文件6对应的checkpoint_change#被刷新了,last_change#变为null,文件头的checkpoint_change#被更新为v$datafile一样的值,处于一致性状态。只是该checkpoit_change#的值跟其他数据文件和v$database的不一样,而且要大一点。
SQL> alter tablespace test1 online;
表空间已更改。
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
2131052
SQL> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 2131052
2 2131052
3 2131052
4 2131052
5 2131052
6 2131339
已选择6行。
SQL> select file#,checkpoint_change#,last_change# from v$datafile;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 2131052
2 2131052
3 2131052
4 2131052
5 2131052
6 2131339
已选择6行。
SQL>
另外,还有就是,让表空间read only或者read write同样会触发局部检查点。如下:
SQL> alter tablespace test01 read only;
Tablespace altered.
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
1146576
SQL> select file#,checkpoint_change# from v$datafile_header where file#=6;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
6 1147039
SQL> select file#,checkpoint_change#,last_change# from v$datafile where file#=6;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
6 1147039 1147039
SQL> alter tablespace test01 read write;
Tablespace altered.
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
1146576
SQL> select file#,checkpoint_change# from v$datafile_header where file#=6;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
6 1147172
SQL> select file#,checkpoint_change#,last_change# from v$datafile;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
6 1147172