检查点 机制mysql_深入解析检查点的触发机制

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]

阅读(3974) | 评论(0) | 转发(0) |

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值