Chinaunix首页 | 论坛 | 博客
  • 博客访问: 506112
  • 博文数量: 101
  • 博客积分: 1635
  • 博客等级: 上尉
  • 技术积分: 1282
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-05 01:51
文章分类

全部博文(101)

文章存档

2019年(2)

2018年(16)

2013年(14)

2012年(69)

我的朋友

分类: Oracle

2019-01-30 14:12:14

checkpoint触发的条件
1)手工触发
当手工发出alter system checkpoint 等命令时触发(实际上alter system flush buffer chache 也会触发)
一般我们在进行重大操作的时,可以手工触发检查点,然后多切换几次redo logfile,再去shutdown.这样可以保证数据库的脏块尽可能的都完全写入到disk中,同时也能保证实例open时,能尽可能快的打开。
2) redo switch
从8i之后版本,redo切换已经视为增量检查点了
oracle是日志写优先原则,在进行日志切换时,即将写next redo时,lgwr进程会post信息给dbwr进程,去写buffer cache中的脏块。如果归档的话,同时还会post给arch进程。
3)对象检查点
这主要是指DDL操作,比如我们drop 某个表或truncate某个表。当ddl发生后,会触发dbwn进程将buffer cache 中该对象相关的所有脏块都写入到disk中。我们知道dbwn进行写脏块,是通过扫描dbwn的LRU链表,如果我们的
cache buffer很大,那么这个扫描链表的操作会很长。
案例drop user 时间很长,减少buffer 的大小。
通常有2个等待事件:
enq:RO -fast object reuse
enq:KO-fast object checkpoint
4)并行查询触发检查点
出现direct path read.直接路劲读是绕过buffer cache的。当绕过buffer cache后,直接从文件中读取某个块,而可能改块正好在buffer cache中北修改,这个时候可能出现数据库块版本不一致的情况。为了防止这样的情况,所以oracle
在这是引入检查点,就是object级别的检查点,去保障数据块版本的一致性。
5)3s check机制

1. full chekcpoint的一些基础知识
我们汉子道检查点其实是一个数据库事件,它存在的目的其实有2个:
1)建立数据的一致性
2)保证数据库尽可能快的恢复
full chekcpoint检查点的分类以及检查点的触发机制:
主要有如下几种触发机制:
--手工触发
--日志切换
--object 检查点
--并行查询
--3s check机制
检查点触发后会post信息给dbwn进程去写dirty block.那么dbwn进程写脏块的条件有哪些?
1)oracle shadow 进程扫描cache buffer链表超过25%,会触发,同时如果扫描达到40%后,仍然没有空闲buffer可用,
那么会post信息给dbwn去将buffer cache中的脏块写入到disk中。这2个机制是通过如下参数来控制的:
SQL> show parameter dirty


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
_db_large_dirty_queue                integer     25
SQL> show parameter db_block_max


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
_db_block_max_cr_dba                 integer     6
_db_block_max_scan_pct               integer     40
这里dbwn进程写脏块的顺序是怎么样的?根据chekcpoint queue来进行的,根据checkpoint queue将脏块按照seq进行顺序的写入到disk中。


SQL> alter system checkpoint;


System altered.


SQL> select file#,checkpoint_change# from v$datafile order by 1;


     FILE# CHECKPOINT_CHANGE#
---------- ------------------
         1            7867966
         2            7867966
         4            7867966
         5            7867966
         6            7867966


SQL> select file#,checkpoint_change# from v$datafile_header order by 1;


     FILE# CHECKPOINT_CHANGE#
---------- ------------------
         1            7867966
         2            7867966
         4            7867966
         5            7867966
         6            7867966


SQL>  select rtckp_rba_seq||'.'||rtckp_rba_bno||'.'|| rtckp_rba_bof "RBA",rtckp_scn from x$kccrt;


RBA                                      RTCKP_SCN
---------------------------------------- ----------------
323.2661.16                              7867966




查看alert此时的日志
Beginning global checkpoint up to RBA [0x143.a65.10], SCN: 7867966
Completed checkpoint up to RBA [0x143.a65.10], SCN: 7867966
0x143.a65.10转换成十进制是323.2661.16


BBED> set file 5 block 1
        FILE#           5
        BLOCK#          1


BBED> p kcvfhckp
struct kcvfhckp, 36 bytes                   @484     
   struct kcvcpscn, 8 bytes                 @484     
      ub4 kscnbas                           @484      0x00780e3e
      ub2 kscnwrp                           @488      0x0000
   ub4 kcvcptim                             @492      0x3b33782c
   ub2 kcvcpthr                             @496      0x0001
   union u, 12 bytes                        @500     
      struct kcvcprba, 12 bytes             @500     
         ub4 kcrbaseq                       @500      0x00000143
         ub4 kcrbabno                       @504      0x00000a65
         ub2 kcrbabof                       @508      0x0010
   ub1 kcvcpetb[0]                          @512      0x02
   ub1 kcvcpetb[1]                          @513      0x00
   ub1 kcvcpetb[2]                          @514      0x00
   ub1 kcvcpetb[3]                          @515      0x00
   ub1 kcvcpetb[4]                          @516      0x00
   ub1 kcvcpetb[5]                          @517      0x00
   ub1 kcvcpetb[6]                          @518      0x00
   ub1 kcvcpetb[7]                          @519      0x00
---------------
占用12个字节
  struct kcvcprba, 12 bytes             @500     
         ub4 kcrbaseq                       @500      0x00000143   ------redo的seq的值
         ub4 kcrbabno                       @504      0x00000a65
         ub2 kcrbabof                       @508      0x0010


1)什么是增量检查点
我们知道oracle引入检查点机制的目的,是尽可能的降低实例恢复的时间,然后由于以前的版本只有full checkpoint,而每次触发full checkpoint都必须让dbwn进程将
cache buffer的所有脏块写入到disk中。对于一个大型OLTP系统而言,将所有脏块写入到disk中,会产生巨大的IO消耗,而且一旦此时数据库crash,那么实例恢复的时间会
相当的漫长。
故oracle引入增量检查点,这样让dbwn写脏块的频率变的更高一些,不仅可以缓解io压力,同时也能降低实例恢复的时间。oracle8i开始引入增量检查点。
2) 增量检查点相关的参数
log_checkpoint_interval 设定两次checkpoint之间重做日志块数量,当重做日志块数量达到设定值的时候将触发checkpoint.
log_checkpoint_timeout 设定两次checkpoint之间的间隔时间,当超时增量checkpoint将被触发。 ORACLE建议不用这个参数来控制,因为事务大小不是按时间等量分布的。单位是秒。
fast_start_io_target 因为log_checkpoint_interval主要看的是重做日志块的数量,并不能反映buffer cache中脏数据块的修改,因此oracle又引入了这个参数来实现当脏块达到一定数量
的时候触发checkpoint,不过此参数实际上控制的是恢复时所需IO的数量。
从9i,oracle引入了新的参数来代替上面的几个参数:
fast_start_mttr_target
关于该参数,一旦你设置之后,上面的几个参数的值就是通过这个参数来计算的。


SQL> select  tt.TARGET_MTTR,tt.ESTIMATED_MTTR,tt.CKPT_BLOCK_WRITES,tt.CKPT_BLOCK_WRITES from v$instance_recovery tt ;


TARGET_MTTR ESTIMATED_MTTR CKPT_BLOCK_WRITES CKPT_BLOCK_WRITES
----------- -------------- ----------------- -----------------
          0              7              1300              1300


从10g开始,oracle引入了增量检查点的自动调节机制:


SQL> show parameter checkpoint


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
_disable_incremental_checkpoints     boolean     FALSE  --决定是否启动增量检查点。
_disable_selftune_checkpointing      boolean     FALSE 决定是否启动增量检查点自动调节。
_gc_global_checkpoint_scn            boolean     TRUE
_kdli_checkpoint_flush               boolean     FALSE
_log_checkpoint_recovery_check       integer     0
_selftune_checkpoint_write_pct       integer     3  是一个百分比
_selftune_checkpointing_lag          integer     300 默认值300s
log_checkpoint_interval              integer     0
log_checkpoint_timeout               integer     1800
log_checkpoints_to_alert             boolean     TRUE


3)增量检查点的实质


增量检查点不会更新datafile header,仅仅是更新controlfile。记住redo switch也是会触发增量检查点的。但是redo switch所触发增量检查点,并不是真正的增量检查点,
因为它会更新controlfile和datafile header。


通过实验观察一下:
++++++++++session1
SQL> col "RBA" for a30;
SQL> select rtckp_rba_seq||'.'||rtckp_rba_bno||'.'|| rtckp_rba_bof "RBA",rtckp_scn from x$kccrt;


RBA                            RTCKP_SCN
------------------------------ ----------------
325.2.16                       7931250


SQL> oradebug setmypid
Statement processed.
SQL> alter session set events 'immediate trace name controlf level 3';


Session altered.


SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_12817.trc


此时观察一个datafie header 的checkpoint信息:
BBED>  p kcvfhckp
struct kcvfhckp, 36 bytes                   @484     
   struct kcvcpscn, 8 bytes                 @484     
      ub4 kscnbas                           @484      0x00790572
      ub2 kscnwrp                           @488      0x0000
   ub4 kcvcptim                             @492      0x3b3476a5
   ub2 kcvcpthr                             @496      0x0001
   union u, 12 bytes                        @500     
      struct kcvcprba, 12 bytes             @500     
         ub4 kcrbaseq                       @500      0x00000145
         ub4 kcrbabno                       @504      0x00000002
         ub2 kcrbabof                       @508      0x0010
   ub1 kcvcpetb[0]                          @512      0x02
   ub1 kcvcpetb[1]                          @513      0x00
   ub1 kcvcpetb[2]                          @514      0x00
   ub1 kcvcpetb[3]                          @515      0x00
   ub1 kcvcpetb[4]                          @516      0x00
   ub1 kcvcpetb[5]                          @517      0x00
   ub1 kcvcpetb[6]                          @518      0x00
   ub1 kcvcpetb[7]                          @519      0x00


++++++++session2
进行大量的dml操作
SQL> delete from tt where rownum<200;


199 rows deleted.


SQL> commit;


Commit complete.


SQL> delete from tt where rownum<10000;


9999 rows deleted.


SQL> commit;


Commit complete.


SQL> insert into tt values(22);


1 row created.


SQL> commit;


Commit complete.
----------session3
SQL> oradebug setmypid
Statement processed.
SQL> alter session set events 'immediate trace name controlf level 3';


Session altered.


SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_12893.trc
此时再次观察datafile checkpint信息:
BBED> p kcvfhckp
struct kcvfhckp, 36 bytes                   @484     
   struct kcvcpscn, 8 bytes                 @484     
      ub4 kscnbas                           @484      0x00790572
      ub2 kscnwrp                           @488      0x0000
   ub4 kcvcptim                             @492      0x3b3476a5
   ub2 kcvcpthr                             @496      0x0001
   union u, 12 bytes                        @500     
      struct kcvcprba, 12 bytes             @500     
         ub4 kcrbaseq                       @500      0x00000145
         ub4 kcrbabno                       @504      0x00000002
         ub2 kcrbabof                       @508      0x0010
   ub1 kcvcpetb[0]                          @512      0x02
   ub1 kcvcpetb[1]                          @513      0x00
   ub1 kcvcpetb[2]                          @514      0x00
   ub1 kcvcpetb[3]                          @515      0x00
   ub1 kcvcpetb[4]                          @516      0x00
   ub1 kcvcpetb[5]                          @517      0x00
   ub1 kcvcpetb[6]                          @518      0x00
   ub1 kcvcpetb[7]                          @519      0x00


之前的:
DATA FILE #5: 
  name #5: /u01/app/oracle/oradata/orcl/tbs_unvdata01.dbf
creation size=0 block size=8192 status=0xe head=5 tail=5 dup=1
 tablespace 6, index=4 krfil=5 prev_file=0
 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
 Checkpoint cnt:187 scn: 0x0000.00790572 11/27/2018 10:59:49
 Stop scn: 0xffff.ffffffff 11/22/2018 10:03:22
 Creation Checkpointed at scn:  0x0000.004f62b1 10/16/2018 17:49:00
 thread:0 rba:(0x0.0.0)


之后的:
DATA FILE #5: 
  name #5: /u01/app/oracle/oradata/orcl/tbs_unvdata01.dbf
creation size=0 block size=8192 status=0xe head=5 tail=5 dup=1
 tablespace 6, index=4 krfil=5 prev_file=0
 unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
 Checkpoint cnt:187 scn: 0x0000.00790572 11/27/2018 10:59:49
 Stop scn: 0xffff.ffffffff 11/22/2018 10:03:22
 Creation Checkpointed at scn:  0x0000.004f62b1 10/16/2018 17:49:00
 thread:0 rba:(0x0.0.0)


orcl_ora_12817.trc
***************************************************************************
CHECKPOINT PROGRESS RECORDS
***************************************************************************
 (size = 8180, compat size = 8180, section max = 11, section in-use = 0,
  last-recid= 0, old-recno = 0, last-recno = 0)
 (extent = 1, blkno = 2, numrecs = 11)
THREAD #1 - status:0x2 flags:0x0 dirty:50
low cache rba:(0x145.1051.0) on disk rba:(0x145.10c4.0)
on disk scn: 0x0000.00790b6e 11/27/2018 11:22:53
resetlogs scn: 0x0000.000e2006 09/14/2018 11:30:48
heartbeat: 993285236 mount id: 1521006257




orcl_ora_12893.trc
***************************************************************************
CHECKPOINT PROGRESS RECORDS
***************************************************************************
 (size = 8180, compat size = 8180, section max = 11, section in-use = 0,
  last-recid= 0, old-recno = 0, last-recno = 0)
 (extent = 1, blkno = 2, numrecs = 11)
THREAD #1 - status:0x2 flags:0x0 dirty:213
low cache rba:(0x145.10c4.0) on disk rba:(0x145.25bd.0)
on disk scn: 0x0000.00790c4c 11/27/2018 11:27:53
resetlogs scn: 0x0000.000e2006 09/14/2018 11:30:48
heartbeat: 993285346 mount id: 1521006257


从上面可以得出一下结论:
1)增量检查点仅仅更新controlfile,不会更新datafile header中的checkpoint的信息。
2)增量检查点会仅仅是controlfile中的checkpoint progress records记录中的如下信息:
low cache rba ,on disk rba ,on disk scn不会去更新controlfile中datafile对应的checkpoint scn等信息。






alter system switch logfile;
更新了checkpoint rba信息,同时datafile header的checkpoint scn信息也更新了。


实际上,检查点队列就是一个列表,而这个列表上包含一系列的buffer cache中的脏块,当然这些脏块的顺序是最早被修改的脏块放在前面,稍后修改的脏块在后面,
总之是根据time来排序的。
checkpoint queue是一个列表,每个checkpointqueue的一个位置我们称职为postion,当然这个postion就是通过rba来表示的。所以你可以理解为:
checkpoint queue就是一些脏块对应的buffer header列表,每个buffer header里面还包含了rba信息,只是这些rba是有一定顺序的。
每个rba都对应buffer cache中的一个脏块,而脏块这里也是分时间前后的,所以对应的checkpoint queue 上的checkpoint rba也是分先后的。


1)这里补充一点,dbwn进程要写脏块,那么久需要扫描LRU链表,在扫描之前需要先获得 cache buffer lru chains这个latch。
还有,dbwn进行在修改buffer cache中的数据之前,需要获得一个free buffer。cache buffer是被划分成多个buffer pool,然后,每个buffer pool里面的free buffer 是通过hash bucket
来管理的。当然,bucket的个数,是通过oracle隐含参数来控制:
SQL> show parameter db_block_hash


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
_db_block_hash_buckets               integer     65536
_db_block_hash_latches               integer     2048
2) buffer header dump
SQL> oradebug setmypid
Statement processed.
SQL> alter session set events ' immediate trace name buffers level 1';


Session altered.


SQL> oradebug close_trace
Statement processed.
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_14141.trc
Dump of buffer cache at level 1 for tsn=2147483647 rdba=0
BH (0x647ea7f0) file#: 2 rdba: 0x00813c80 (2/81024) class: 8 ba: 0x6461c000
  set: 20 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,0
  dbwrid: 0 obj: 6592 objn: 6592 tsn: 1 afn: 2 hint: f
  hash: [0x710f89b0,0x710f89b0] lru: [0x67bf1420,0x6d3e33e0]
  lru-flags: hot_buffer
  ckptq: [NULL] fileq: [NULL] objq: [0x6b3e2b80,0x612d6988] objaq: [0x6afe6748,0x612d6978]
  st: XCURRENT md: NULL fpin: 'ktspfwh10: ktspscan_bmb' tch: 0
  flags: block_written_once redo_since_read
  LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [3]
BH (0x6cfd7e90) file#: 2 rdba: 0x00821a9c (2/137884) class: 1 ba: 0x6cc34000
  set: 17 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,0
  dbwrid: 0 obj: 87239 objn: 87239 tsn: 1 afn: 2 hint: f
  hash: [0x710f8a00,0x710f8a00] lru: [0x6cfd7d10,0x6c3e7958]
  lru-flags: hot_buffer
  ckptq: [NULL] fileq: [NULL] objq: [0x61299158,0x61299158] objaq: [0x61299148,0x61299148]
  st: XCURRENT md: NULL fpin: 'ktspbwh1: ktspfsrch' tch: 1
  flags: block_written_once redo_since_read
  LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [1]
























阅读(5976) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~