什么是checkpoint:
checkpoint是数据库的一个内部事件,检查点激活时会触发数据库写进程(DBWR),将数据缓冲区里的脏数据块写到数据文件中。
checkpoint主要的2个作用:
1)保证数据库的一致性,这是指将脏数据写出到硬盘,保证内存和硬盘上的数据是一样的;
2)缩短实例恢复的时间,实例恢复把实例异常关闭前没有写到硬盘的脏数据通过日志进行恢复。如果脏块过多,实例恢复的时间也会很长,检查点的发生可以减少脏块的数量,从而提高实例恢复的时间。
checkpoint分类:
完全检查点 full checkpoint
增量检查点 incremental checkpoint
局部检查点 partical checkpoint
完全检查点工作方式:
记下当前的scn,将此scn之前所有的脏块一次性写完,再将该scn号同步更新控制文件和数据文件头
可以引起完全检查点的两个动作
正常关闭数据库:shutdown immediate
手动检查点切换:alter system checkpoint
以上会同步更新: 系统检查点,数据文件检查点,数据文件头检查点,将数据缓冲区里的脏数据写到数据文件中。
增量检查点概念及相关参数
概念:
1)一般来说增量检查点不会更新数据文件头和控制文件的SCN,它只是根据策略计算一个SCN(未必是当前SCN),将此SCN前的脏块刷新到磁盘,这个SCN点也叫检查点位置,然后将与此SCN有关的信息记录到控制文件。
2)被修改过的块,在oracle中都被通称为脏块,所有的脏块被一个双向链表串起来,称做检查点队列checkpoint queue。
增量检查点的目的:保证脏块的数量是可控的
3)脏块按照首次变脏的时间书序排列,DBWR每到一定的时机就会被触发,沿着检查点队列的顺序将脏块刷新到磁盘上。检查点位置之前的块,都是已被DBWR刷新到磁盘上的块。而最后的检查点位置,总是被记录在控制文件中。如果发生系统崩溃的话,这个最后一次的检查点位置就是实例恢复的起点。
4)当增量检查点发生时,Oracle会写一部分脏块,使检查点位置前移。进而缩短实例恢复需要的日志起点和终点之间的距离,触发增量检查点越频繁,这个距离就越短,那么它也就使实例恢复的时间越少,但数据库性能受到频繁IO影响会降低。
与增量检查点有关的几个知识点:
FAST_START_MTTR_TARGET参数
如何有效的缩短最近检查点位置与联机重做日志尾部之间的距离,正式设计次参数目的。
此参数单位为秒。缺省值900,范围0-3600秒,判定依据是当内存中产生的dirty buffer所需的日志恢复时间(estimated_mttr)如果到达该参数指定时间,则增量检查点被处罚。fast_start_mttr_target如果为0,Oracle则是根据DBWN进程自身需要尽量减少写入量,这样虽然实现了性能最大化,但实力恢复时间可能会比较长。
※ 此参数并不是将脏列表中的所有脏块都写到数据文件中,而是写出一部分,保证满足条件即可。
※ 如果将fast_start_mttr_target设置为非0,将启用检查点自动调整机制。
※ 验证以上概念的一个有效的方法,可以研究一下日志切换:alter system switch logfile:这个动作比较特殊,其特征是完全检查点和增量检查点综合的效果。
如果FAST_START_MTTR_TARGET为非0,将启用检查点自动调整机制(增量检查点机制启动),v$log视图中的active状态几分钟后会变成inactive状态,然后更新了控制文件和日志文件头部的SCN(这是完全检查点的特征)
下面来验证一下
当fast_start_mttr_target 参数为非0值时,日志状态由active变为inactive时,控制文件和日志文件头部的SCN会不会变化
idle>show parameter mttr //查看fast_start_mttr_target 参数
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fast_start_mttr_target integer 0
idle>
idle>
idle>alter system set fast_start_mttr_target=900 //将参数fast_start_mttr_target 设置为900
2 ;
System altered.
idle>show parameter mttr //参数设置成功
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fast_start_mttr_target integer 900
idle>
idle>
idle>select * from v$log; //group1为current状态
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------
1 1 17 52428800 512 2 NO CURRENT 1793435 03-AUG-19 2.8147E+14
2 1 15 52428800 512 2 NO INACTIVE 1765577 30-JUL-19 1786740 30-JUL-19
3 1 16 52428800 512 2 NO INACTIVE 1786740 30-JUL-19 1793435 03-AUG-19
4 1 14 8388608 512 2 NO INACTIVE 1744763 30-JUL-19 1765577 30-JUL-19
idle>alter system switch logfile; //切换日志
System altered.
idle>select * from v$log; //当前group1为active状态
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------
1 1 17 52428800 512 2 NO ACTIVE 1793435 03-AUG-19 1796209 03-AUG-19
2 1 15 52428800 512 2 NO INACTIVE 1765577 30-JUL-19 1786740 30-JUL-19
3 1 16 52428800 512 2 NO INACTIVE 1786740 30-JUL-19 1793435 03-AUG-19
4 1 18 8388608 512 2 NO CURRENT 1796209 03-AUG-19 2.8147E+14
idle>
idle>
idle>select file#,checkpoint_change# from v$datafile; //这里留意一下scn号为1795922
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1795922
2 1795922
3 1795922
4 1795922
5 1795922
idle>select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1795922
2 1795922
3 1795922
4 1795922
5 1795922
idle>select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------
1 1 17 52428800 512 2 NO ACTIVE 1793435 03-AUG-19 1796209 03-AUG-19
2 1 15 52428800 512 2 NO INACTIVE 1765577 30-JUL-19 1786740 30-JUL-19
3 1 16 52428800 512 2 NO INACTIVE 1786740 30-JUL-19 1793435 03-AUG-19
4 1 18 8388608 512 2 NO CURRENT 1796209 03-AUG-19 2.8147E+14
idle>
idle>
idle>select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------
1 1 17 52428800 512 2 NO ACTIVE 1793435 03-AUG-19 1796209 03-AUG-19
2 1 15 52428800 512 2 NO INACTIVE 1765577 30-JUL-19 1786740 30-JUL-19
3 1 16 52428800 512 2 NO INACTIVE 1786740 30-JUL-19 1793435 03-AUG-19
4 1 18 8388608 512 2 NO CURRENT 1796209 03-AUG-19 2.8147E+14
idle>select * from v$log; //当group1的active变为inactive状态的时候,我们再来看v$datafile和v$datafile_header里的scn号,会变为新的
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ ---------
1 1 17 52428800 512 2 NO INACTIVE 1793435 03-AUG-19 1796209 03-AUG-19
2 1 15 52428800 512 2 NO INACTIVE 1765577 30-JUL-19 1786740 30-JUL-19
3 1 16 52428800 512 2 NO INACTIVE 1786740 30-JUL-19 1793435 03-AUG-19
4 1 18 8388608 512 2 NO CURRENT 1796209 03-AUG-19 2.8147E+14
idle>select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1796209
2 1796209
3 1796209
4 1796209
5 1796209
idle>select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1796209
2 1796209
3 1796209
4 1796209
5 1796209
idle>
※ 如果FAST_START_MTTR_TARGET=0,则关闭检查点自动机制,只能靠DBWN进程自身机制写脏块,如没有太多事务发生,active很长时间状态不变。
※ 90% OF SMALLEST REDO LOG(Oracle 内部参数),将重做日志文件末尾前面90%的位置设置为检查点位置。
※ 每3s查看checkpoint队列脏块的写出进度,注意,3s不出发检查点,他只是记录当时的检查点位置,并将相关信息写入到controlfile。
实例恢复有关的顾问叫做MTTR Advisory
需要设置两个参数
1)STATISTICS_LEVEL > 设置为typical(缺省)或者all
2)FAST_START_MTTR_TARGET > 设置为非零值
设置合理的MTTR参数
查看视图 v$instance_recovery
idle>select recovery_estimated_ios,actual_redo_blks,target_redo_blks,target_mttr,estimated_mttr from v$instance_recovery;
RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR
---------------------- ---------------- ---------------- ----------- --------------
48 162 1941 20 8
idle>
//系统计算出来的target_mttr为33秒,当前估算的恢复时间是8秒。
总结:
从领导和顾客的需求来分析,他们只关心多长时间能够恢复实例,因为每推迟一分钟都是很大的损失
假设需求是5分钟恢复实例,那么把5分钟这个参数给FAST_START_MTTR_TARGET
Oracle根据5分钟去折算有多少脏块可以在5分钟内搞定,进而折算出检查点的触发条件,保证检查点的频率不断的去写脏块能够保证到5分钟的存量.
但是如果该参数设成1分钟呢?
有人想这样不就可以保证能够在很短的时间内进行实例恢复,减少损失了。
但实际并不是这样,这样的结果会导致频繁的写脏块,增加IO,导致数据库性能降低
所以FAST_START_MTTR_TARGET的值既不能设置太大,也不能太小
局部检查点的触发条件
对于某些操作,局部检查点是必须的,并会自动执行。
比如:表空间offline,数据文件offline,删除extent,表truncate,begin backup(将表空间置于备份模式)等。Oracle会根据需要自动执行。