【数据库管理】⑧检查点checkpoint
【数据库管理】⑧检查点checkpoint
1. checkpoint的本质
Checkpoint是Oracle数据库中的一种机制,用于将内存中的数据写入磁盘,以保证数据的持久性和一致性。Checkpoint的本质是将数据库中的脏数据(即已经被修改但还没有写入磁盘的数据)写入磁盘,同时更新数据库的控制文件和日志文件,以便在数据库恢复时能够正确地恢复数据。
Checkpoint的实现方式是通过Oracle后台进程LGWR(Log Writer)来完成的。LGWR会定期将内存中的脏数据写入磁盘,并更新数据库的控制文件和日志文件。同时,它还会将写入磁盘的数据标记为干净数据(即已经被写入磁盘的数据),以便在数据库恢复时能够正确地恢复数据。
Checkpoint的频率和方式可以通过Oracle参数进行配置。一般来说,较小的Checkpoint间隔可以提高数据库的性能,但会增加磁盘I/O负载;较大的Checkpoint间隔可以减少磁盘I/O负载,但会降低数据库的性能。因此,在实际应用中,需要根据实际情况来配置Checkpoint的频率和方式,以保证数据库的性能和可用性。
当修改数据时,需要首先将数据读入内存中(Buffer Cache),同时,Oracle会记录Redo log用于恢复.因为有了Redo log的存在,Oracle不需要在提交时立即将变化的数据写回磁盘(立即写的效率会很低), Redo log的存在也正是为了在数据库崩溃之后, 可以恢复数据.
最常见的情况,数据库可以因为断电而Crash,那么内存中修改过的、尚未写入文件的数据将会丢失.在下一次数据库启动之后,Oracle可以通过重做日志(Redo)进行事务重演,也就是进行前滚,将数据库恢复到崩溃之前的状态,然后数据库可以打开继续使用,之后Oracle可以回滚未提交的数据.
在这个过程中,最重要的是数据库要经历多久才能打开.也就是需要读取多少重做日志才能完成前滚.这个时间越短越好.
检查点的存在就是为了缩短这个恢复时间.
当检查点发生时(此时的SCN被称为CheckPoint SCN),Oracle会通知DBWR进程,把修改过的数据,也就是Checkpoint SCN之前的脏数据(Dirty Data)从Buffer Cache写入磁盘,当写入完成之后,CKPT进程更新控制文件和数据文件头,记录检查点信息,标识变更.
在检查点完成之后,此检查点之前修改过的数据都已经写回磁盘,重做日志文件中的相应重做记录对于崩溃/实例恢复不再有用.
2. checkpoint主要作用
Checkpoint的主要作用是保证数据库的持久性和一致性。具体来说,Checkpoint可以实现以下几个方面的作用:
将内存中的脏数据写入磁盘:Checkpoint可以将内存中的脏数据(即已经被修改但还没有写入磁盘的数据)写入磁盘,以保证数据的持久性和一致性。这样,在数据库发生故障或崩溃时,可以通过恢复日志将数据恢复到最近的Checkpoint时刻。
更新数据库的控制文件和日志文件:Checkpoint可以更新数据库的控制文件和日志文件,以便在数据库恢复时能够正确地恢复数据。控制文件包含了数据库的结构信息和状态信息,而日志文件则记录了数据库的所有修改操作,包括数据的插入、更新和删除等操作。
释放未使用的空间:Checkpoint可以释放未使用的空间,以便将空间回收给操作系统。这样可以减少数据库的存储空间占用,同时也可以提高数据库的性能。
提高数据库的性能和可用性:Checkpoint可以减少数据库的I/O负载,从而提高数据库的性能和可用性。当数据库中存在大量的脏数据时,Checkpoint可以将这些数据写入磁盘,从而减少内存中的脏数据量,提高数据库的性能和可用性。
需要注意的是,Checkpoint的频率和方式可以通过Oracle参数进行配置。在实际应用中,需要根据实际情况来配置Checkpoint的频率和方式,以保证数据库的性能和可用性。同时,还需要定期监控Checkpoint的使用情况,以及进行Checkpoint的维护和优化。
3. checkpoint分类
在Oracle数据库中,Checkpoint可以分为以下几种类型:
1.Complete Checkpoint:完全Checkpoint是最常见的一种Checkpoint类型,它会将所有脏数据都写入磁盘,并更新数据库的控制文件和日志文件。完全Checkpoint会在以下情况下发生:
- 执行ALTER SYSTEM CHECKPOINT命令时;
- 数据库关闭时;
- 数据库实例崩溃时。
2.Incremental Checkpoint:增量Checkpoint是一种优化的Checkpoint类型,它只会将一部分脏数据写入磁盘,而不是全部写入。增量Checkpoint会在以下情况下发生:
- 每隔一段时间(由参数FAST_START_MTTR_TARGET控制);
- 当脏数据量达到一定阈值(由参数LOG_CHECKPOINT_INTERVAL控制);
- 当数据库实例崩溃时。
3.Thread Checkpoint:线程Checkpoint是一种特殊的Checkpoint类型,它只会将某个线程的脏数据写入磁盘,而不是全部线程的脏数据。线程Checkpoint会在以下情况下发生:
- 当某个线程的脏数据量达到一定阈值(由参数LOG_CHECKPOINT_TIMEOUT控制);
- 当数据库实例崩溃时。
需要注意的是,Checkpoint的类型和频率可以通过Oracle参数进行配置。在实际应用中,需要根据实际情况来选择最适合的Checkpoint类型和频率,以保证数据库的性能和可用性。同时,还需要定期监控Checkpoint的使用情况,以及进行Checkpoint的维护和优化。
4. 完全检查点
4.1 工作方式
记下当前的scn, 将此scn之前所有的脏块一次性写完,再将该scn号同步更新控制文件和数据文件头.
4.2 可以引起完全检查点的动作
a)正常关闭数据库 : shutdown immediate
b)手动切换检查点 : alter system checkpoint;
c)日志切换 : alter system switch logfile; --FAST_START_MTTR_TARGET 非0时,作用于增量检查点
d)数据库热备模式 : alter database begin backup;
4.3 验证
记下当前的SCN号(因为Oracle自身运行,scn会不停增长)
SQL> select current_scn from v$database;
CURRENT_SCN
-------------------
8609589
SQL> alter system checkpoint;
SQL> Select file#,checkpoint_change# from v$datafile;
-- 然后观察 v$datafile 和 v$datafile_header中scn被更新.
SQL> Select file#,checkpoint_change# from v$datafile_header;
[oracle@MaxwellDBA ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Mon Apr 3 16:50:41 2023
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
sys@cdb$root:orclcdb> show user;
USER is "SYS"
sys@cdb$root:orclcdb>
sys@cdb$root:orclcdb> select current_scn from v$database;
CURRENT_SCN
-----------
31888378
1 row selected.
sys@cdb$root:orclcdb> alter system checkpoint;
System altered.
sys@cdb$root:orclcdb> Select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 31888385
3 31888385
4 31888385
5 2153651
6 2153651
7 31888385
8 2153651
9 31888385
10 31888385
11 31888385
12 31888385
11 rows selected.
sys@cdb$root:orclcdb> -- 然后观察 v$datafile 和 v$datafile_header中scn被更新.
sys@cdb$root:orclcdb> Select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 31888385
3 31888385
4 31888385
5 2153651
6 2153651
7 31888385
8 2153651
9 31888385
10 31888385
11 31888385
12 31888385
11 rows selected.
sys@cdb$root:orclcdb>
5. 增量检查点及相关参数
5.1 概述
1).被修改过的块被统称为脏块.脏块按照首次变脏的时间顺序被一个双向链表指针串联起来,称做检查点队列(checkpoint queue).
2).当增量检查点发生时,DBWR就会被触发,沿着检查点队列的顺序将部分脏块刷新到磁盘上,每次刷新截止的那个块的位置就叫检查点位置,检查点位置之前的块,都是已经被DBWR刷新到磁盘上的块.而检查点位置对应的日志地址(RBA)又总是被记录在控制文件中(SCN号).如果发生系统崩溃,这个最后的检查点位置就是实例恢复的起点.
3).当增量检查点发生时,Oracle会写一部分脏块,使检查点位置前移.进而缩短实例恢复需要的日志起点和终点之间的距离,触发增量检查点越频繁,实例恢复的时间越少(脏块少了),但数据库性能受到频繁IO影响会降低.
4).增量检查点不会同步更新数据文件头和控制文件的SCN. 它只是根据策略计算一个SCN(未必是当前的SCN),将此SCN前的脏块刷新到磁盘,这个SCN点也叫检查点位置,然后将与此SCN有关的信息记录到控制文件中.(说明刷新一部分)
5.2 FAST_START_MTTR_TARGET参数
这个参数是NOTE.它定义多长时间恢复实例.(如何有效的缩短最近检查点位置与联机重做日志尾部之间的距离,正是设计此参数目的)
此参数单位为秒,缺省值0,范围0-3600秒,根据这个参数,Oracle计算出在内存中累积的 dirty buffer所需的日志恢复时间,如果到达该参数指定的时间,则增量检查点进程被触发.
该参数如果为0(增量检查点关掉),ORACLE则会根据DBWR进程自身需要尽量减少写入量,这样虽然实现了性能最大化,但实例恢复时间可能会比较长.
此参数并不是将脏块列表中所有脏块都写到数据文件中,而是一部分,保证满足条件即可.
早期还有几个有关增量检查点的参数,
log_checkpoint_interval
:规定了redo日志积累多少block后激活增量检查点*,对用户来讲要给出这个参数不太方便,所谓block指的是os block,*而不是oracle block.
log_checkpoint_timeout
:给一个触发增量检查点的间隔**,**单位是秒.
如果设置了FAST_START_MTTR_TARGET参数*,就不要用早期的一些参数,容易引起冲突.*
5.3 实验alter system switch logfile;
5.3.1 设置FAST_START_MTTR_TARGET
sys@cdb$root:orclcdb>
sys@cdb$root:orclcdb> show parameter fast
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fast_start_io_target integer 0
fast_start_mttr_target integer 0
fast_start_parallel_rollback string LOW
sys@cdb$root:orclcdb> alter system set fast_start_mttr_target=900;
System altered.
sys@cdb$root:orclcdb> show parameter fast;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fast_start_io_target integer 0
fast_start_mttr_target integer 900
fast_start_parallel_rollback string LOW
sys@cdb$root:orclcdb>
5.3.2 查询v$log
sys@cdb$root:orclcdb>
sys@cdb$root:orclcdb> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME CON_ID
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------------------------- ------------ ----------------------------- ----------
1 1 478 209715200 512 1 NO INACTIVE 31754474 02-APR-2023 10:05:28 31823564 02-APR-2023 22:43:38 0
2 1 479 209715200 512 1 NO INACTIVE 31823564 02-APR-2023 22:43:38 31879508 03-APR-2023 14:00:27 0
3 1 480 209715200 512 1 NO CURRENT 31879508 03-APR-2023 14:00:27 1.8447E+19 0
3 rows selected.
sys@cdb$root:orclcdb>
5.3.3 查看数据文件和文件头
sys@cdb$root:orclcdb>
sys@cdb$root:orclcdb> select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 31888385
3 31888385
4 31888385
5 2153651
6 2153651
7 31888385
8 2153651
9 31888385
10 31888385
11 31888385
12 31888385
11 rows selected.
sys@cdb$root:orclcdb> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 31888385
3 31888385
4 31888385
5 2153651
6 2153651
7 31888385
8 2153651
9 31888385
10 31888385
11 31888385
12 31888385
11 rows selected.
sys@cdb$root:orclcdb>
5.3.4 日志切换
sys@cdb$root:orclcdb>
sys@cdb$root:orclcdb> alter system switch logfile;
System altered.
sys@cdb$root:orclcdb>
5.3.5 查询v$log和数据文件
sys@cdb$root:orclcdb> select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 31888385
3 31888385
4 31888385
5 2153651
6 2153651
7 31888385
8 2153651
9 31888385
10 31888385
11 31888385
12 31888385
11 rows selected.
sys@cdb$root:orclcdb> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 31888385
3 31888385
4 31888385
5 2153651
6 2153651
7 31888385
8 2153651
9 31888385
10 31888385
11 31888385
12 31888385
11 rows selected.
sys@cdb$root:orclcdb>
-- 发现checkpoint_change#的值没有变化
-- 切换redo log file后,DBWR写脏块
5.3.6 几分钟后查询
v$log视图中的active状态几分钟后会变成inactive状态(及其对应的脏块写完),然后更新了控制文件和日志文件头部的SCN
sys@cdb$root:orclcdb> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME CON_ID
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------------------------- ------------ ----------------------------- ----------
1 1 481 209715200 512 1 NO CURRENT 31888563 03-APR-2023 16:57:30 1.8447E+19 0
2 1 479 209715200 512 1 NO INACTIVE 31823564 02-APR-2023 22:43:38 31879508 03-APR-2023 14:00:27 0
3 1 480 209715200 512 1 NO INACTIVE 31879508 03-APR-2023 14:00:27 31888563 03-APR-2023 16:57:30 0
3 rows selected.
sys@cdb$root:orclcdb> select file# ,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 31888563
3 31888563
4 31888563
5 2153651
6 2153651
7 31888563
8 2153651
9 31888563
10 31888563
11 31888563
12 31888563
11 rows selected.
sys@cdb$root:orclcdb>
5.4 NOTE
1).如果将 fast_start_mttr_target 设置为非 0
a) 将启用检查点自动调整机制.
b) log_checkpoint_interval参数将被覆盖掉.
2).90% OF SMALLEST REDO LOG(Oarcle 内部机制),将当前日志文件末尾还剩10%的位置设为检查点位置.
3).每3s查看checkpoint队列脏块的写出进度,注意,3s不触发检查点,它只是记录当时的检查点位置,并将相关信息写入到control file.
5.5 MTTR Advisory两个参数
实例恢复有关的顾问叫做MTTR Advisory需要设置两个参数
STATISTICS_LEVEL -->置为typical(缺省) 或者all //影响数据采集
FAST_START_MTTR_TARGET -->置为非零值
5.6 设置合理的MTTR参数
sys@cdb$root:orclcdb>
sys@cdb$root:orclcdb> -- 查看视图 v$instance_recovery
sys@cdb$root:orclcdb> 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
---------------------- ---------------- ---------------- ----------- --------------
1349 10064 24400 56 13
1 row selected.
sys@cdb$root:orclcdb>
6. 局部检查点的触发条件
对于某些操作,局部检查点是必须的,并会自动执行.
比如: tbs offline,datafile offline,删除extent, truncate表,begin backup(将 TBS置于备份模式)等.Oracle会根据需要自动执行.
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)