在 Oracle 的官方文档中介绍 Oracle 的 Checkpoint 有:
(1)Thread Checkpoint;
(2)Tablespace and datafile checkpoint;
(3)Incremental checkpoint。
对 于后两种 checkpoint,大家都有一个比较清晰的认识。 但是对于 Thread checkpoint 和 database checkpoint 之间的关系以及他们在单节点和RAC数据库之间的不同可能存在一些误区。 下面将通过一些例子来讲解一下 Thread checkpoint,以及在单节点和 RAC 中 Thread checkpoint 的不同。
一 单节点数据库(或者是RAC database中,只保留一个节点):
*为了便于观察checkpoint的,设置log_checkpoints_to_alert,让checkpoint的信息打印到alert log中:
SQL> show parameter log_checkpoints_to_alert
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
log_checkpoints_to_alert boolean TRUE
1) 对数据库做"alter system switch logfile":
sys@R11203> select file#, CHECKPOINT_CHANGE# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- --------------------------
1 12717430780764
2 12717430780764
3 12717430780764
4 12717430780764 <<<<<<<<<< 未switch之前
sys@R11203> alter system switch logfile;
System altered.
sys@R11203> select file#, CHECKPOINT_CHANGE# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- --------------------------
1 12717430780764
2 12717430780764
3 12717430780764
4 12717430780764 <<<<<<<<<<<<< switch之后立即查看,v$datafile对应的checkpoint_change#并没有变化。
2)检查一下数据库的alert log:
Tue Jan 19 16:01:02 2016
Beginning log switch checkpoint up to RBA [0x5a.2.10], SCN: 12717430780990 <<<<<<<<<<<<<<
3) 过了大约几分钟后,再次检查 alert log 以及 V$datafile
Tue Jan 19 16:05:58 2016 <<<<<<<<<<<<<<<<<< 16:05 已经结束checkpoint
Completed checkpoint up to RBA [0x5a.2.10], SCN: 12717430780990
sys@R11203> select file#, CHECKPOINT_CHANGE# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- --------------------------
1 12717430780990
2 12717430780990
3 12717430780990
4 12717430780990 <<<<<<<< v$datafile 中的checkpoint check# 已经更改到新的SCN:12717430780990
二 RAC数据库:
1) 对数据库做"alter system switch logfile":
SQL> select INST_ID,INSTANCE_NAME,STATUS from gv$instance;
INST_ID INSTANCE_NAME STATUS
---------- ---------------- ------------
1 ora11g1 OPEN
2 ora11g2 OPEN
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 11583337
2 11583337
3 11583337
4 11583337
5 11583337
6 11583337
6 rows selected.
SQL> alter system switch logfile;
System altered.
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 11583337
2 11583337
3 11583337
4 11583337
5 11583337
6 11583337 <<<<<<<<<
6 rows selected.
2) 观察此节点的alert log:
Wed Jan 20 07:10:16 2016
Beginning log switch checkpoint up to RBA [0x22f.2.10], SCN: 11583841 <<<<<<<<< 开始 log switch的checkpoint。
Thread 1 advanced to log sequence 559 (LGWR switch)
Current log# 1 seq# 559 mem# 0: +DATA1/ora11g/onlinelog/group_1.257.827893181
Wed Jan 20 07:10:16 2016
Completed checkpoint up to RBA [0x22f.2.10], SCN: 11583841 <<<<<<<<<
3) 重新观察一下v$datafile:
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 11583337
2 11583337
3 11583337
4 11583337
5 11583337
6 11583337 <<<<<<<<<<<< checkpoint_change# 还是没有改变。
6 rows selected.
4) 执行"alter system checkpoint"
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 11583337
2 11583337
3 11583337
4 11583337
5 11583337
6 11583337
6 rows selected.
SQL> alter system checkpoint;
System altered.
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 11583983
2 11583983
3 11583983
4 11583983
5 11583983
6 11583983 <<<<<<<<<< 变成: 11583983
6 rows selected.
5) 观察此节点的alert log:
Wed Jan 20 07:14:21 2016
Beginning global checkpoint up to RBA [0x231.3.10], SCN: 11583983 <<<<<<<<<
Completed checkpoint up to RBA [0x231.3.10], SCN: 11583983
6) 那么如果在RAC中做log switch,每次thread checkpoint的记录在哪里可以查询到呢?
SQL> select INSTANCE_NUMBER,INSTANCE_NAME,THREAD#,STATUS from gv$instance;
INSTANCE_NUMBER INSTANCE_NAME THREAD# STATUS
--------------- ---------------- ---------- ------------
1 ora11g1 1 OPEN <<<<<<<<<<<<<<<<<<<
2 ora11g2 2 OPEN
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 11616270
2 11616270
3 11616270
4 11616270
5 11616270
6 11616270
6 rows selected.
SQL> alter system switch logfile;
System altered.
7)在alert log中:
Thu Jan 21 02:22:52 2016
Beginning log switch checkpoint up to RBA [0x23a.2.10], SCN: 11621392
Thread 1 advanced to log sequence 570 (LGWR switch)
Current log# 2 seq# 570 mem# 0: +DATA1/ora11g/onlinelog/group_2.258.827893183
Thu Jan 21 02:22:53 2016
Archived Log entry 358 added for thread 1 sequence 569 ID 0xfbc6d574 dest 1:
Thu Jan 21 02:22:55 2016
Completed checkpoint up to RBA [0x23a.2.10], SCN: 11621392 <<<<<<<<<<<<
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 11616270
2 11616270
3 11616270
4 11616270
5 11616270
6 11616270 <<<<<<<<<< v$datafile中的checkpoint change#照例没有改变。
6 rows selected.
8) 查看v$thread:
SQL> select THREAD#,CHECKPOINT_CHANGE# from v$thread;
THREAD# CHECKPOINT_CHANGE#
---------- ------------------
1 11621392 <<<<<<<<<<<<<<<
2 11619485
总结一下:
1. 对于单节点数据库,由于只有一个thread,所以由log switch发起的对当前thread的checkpoint,实质上就是整个数据库的checkpoint,所以log switch会导致v$datafile (v$datafile_header)中的checkpoint_change#改变。 但是必须要等checkpoint完成以后才会变成最新的值。
2. 对于RAC(2个节点以上)的数据库,由于至少存在2个或者以上的thread,所以对单一thread的 log switch并不会触发v$datafile (v$datafile_header)的checkpoint_change#的修改。原因是:只对其中一个thread(log)cover块的checkpoint,只会触发在此节点上脏块的写回. 但是由于多于2个节点,所以其他的节点可能存在在此checkpoint SCN之前的脏块,所以对于数据文件(或者是数据库)来说,这并不是一个完整的database级的checkpoint。 在RAC中,只有所有节点间的全局检查点(global checkpoint)会导致v$datafile中的checkpoint_change#的变化,比如"alter system checkpoint"。
3. 在RAC中,对于thread的checkpoint_change#,可以通过v$thread来查询。