深入内核:DUMP Block的数据读取与脏数据写入影响

张乐奕

云和恩墨副总经理 Oracle ACE 总监

ITPUB Oracle数据库管理版版主、Oracle高可用版版主、ACOUG联合创始人

如果我们执行alter system dump datafile # block #的话Oracle是否会先把block读入到buffer cache中呢?

简略说一下测试步骤,虽然简单,但还是需要你深入理解Oracle的内部原理。

1。重启一下数据库,这样buffer cache中几乎就没什么用户数据了,方便测试

2。随便找一张表看看是在哪个file哪个block里面

SQL> select header_file,header_block
  2  from dba_segments
  3  where segment_name='T1';
 
HEADER_FILE HEADER_BLOCK
----------- ------------
          4           19

3。T1表在数据文件4中,第一个block是19,检查v$bh,看看这个block有没有在buffer cache中

SQL> select count(*)
  2  from v$bh
  3  where file# = 4 and block# = 19;
 
  COUNT(*)
----------
         0

4。目前buffer cache中没有这个block,作一次dump再看看有没有

SQL> alter system dump datafile 4 block 19;
System altered
 
SQL> select count(*)
  2  from v$bh
  3  where file# = 4 and block# = 19;
 
  COUNT(*)
----------
         0

5。至此验证了作block dump不会把数据块先读入buffer cache,好,继续作一次select看看,这次一定是读进buffer cache了

SQL> select * from ops$kamus.t1;
         N
----------
 
SQL> select count(*)
  2  from v$bh
  3  where file# = 4 and block# = 19;
 
  COUNT(*)
----------
         1

小知识:

1. v$bh视图保存着buffer cache中每一个block的信息。 2. dba_segments视图中一个ASSM类型segment的header_block是从它的PAGETABLE SEGMENT HEADER算起的,并不包括前面用于控制free block的两个位图块(FIRST LEVEL BITMAP BLOCK和SECOND LEVEL BITMAP BLOCK)。

进一步的:dump block会否让刚插入的块写入数据文件呢?

先放出结论:Dump Block不会引起buffer cache中的脏数据回写入磁盘。然后是验证的详细步骤。

1。创建一个测试表

SQL> CREATE TABLE t (n NUMBER);
TABLE created

2。插入一条数据,提交,然后强制checkpoint

SQL> INSERT INTO t VALUES(1);
1 ROW inserted
 
SQL> commit;
Commit complete
 
SQL> ALTER system checkpoint;
System altered

3。此时这条数据一定已经写回磁盘,这个无需验证了,我们继续插入另外一条数据,提交,但是不checkpoint

SQL> INSERT INTO t VALUES(2);
 
1 ROW inserted
 
SQL> commit;
 
Commit complete

4。此时这条脏数据在buffer cache中,我们可以通过dump block来验证

block_row_dump:
tab 0, row 0, @0x1f9a
tl: 6 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 2]  c1 02
tab 0, row 1, @0x1f94
tl: 6 fb: --H-FL-- lb: 0x2  cc: 1
col  0: [ 2]  c1 03
end_of_block_dump

5。通过dbms_rowid包取得T表中所有记录所存储的数据文件号和block号,本例中取得是file#=58, block#=570

6。关键步骤到了,现在我们要用bbed来获取磁盘上的数据块内容,然后跟dump block的结果比较一下

创建一个filelist文件,命名为files.lst。

$ cat files.lst
58 /fin/u06/cnctest2data/system12.dbf 1048576000

创建一个参数文件par.bbd,用以被bbed调用

$ cat par.bbd
blocksize=8192
listfile=/home/oraaux/files.lst
mode=browse

执行bbed

$ bbed parfile=par.bbd
Password: 
 
BBED: Release 2.0.0.0.0 - Limited Production on Mon Mar 13 17:35:32 2006
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
 
BBED> set dba 58,570
        DBA             0x0e80023a (243270202 58,570)
 
BBED> x /*rn rowdata
rowdata[0]                                  @8182    
----------
flag@8182: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8183: 0x01
cols@8184:    1
 
col    0[2] @8185: 1  --只有一条记录,值是1
 
tailchk                                     @8188    
-------
BBED-00210: no row at this offset

到目前为止我们已经验证了dump block并不会把脏数据写回磁盘,为了看一下checkpoint的效果,我们继续往下作。

7。作checkpoint

SQL> ALTER system checkpoint;
 
System altered

8。再次运行bbed

$ bbed parfile=par.bbd
Password: 
 
BBED: Release 2.0.0.0.0 - Limited Production on Mon Mar 13 17:35:32 2006
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
 
BBED> set dba 58,570
        DBA             0x0e80023a (243270202 58,570)
 
BBED> x /*rn rowdata
rowdata[0]                                  @8176    
----------
flag@8176: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8177: 0x02
cols@8178:    1
 
col    0[2] @8179: 2  --这是后来插入的记录,值是2
 
rowdata[6]                                  @8182    
----------
flag@8182: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8183: 0x01
cols@8184:    1
 
col    0[2] @8185: 1  --这是第一条记录,值是1
 
tailchk                                     @8188    
-------
BBED-00210: no row at this offset

checkpoint将buffer cache中的脏数据写回数据文件了。

如果你觉得这个过程太复杂了,当然还有更简单的方法,仍然是v$bh视图,查看v$bh.dirty字段,如果为N表示已经被写入磁盘,如果为Y则表示仍然是脏数据。

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2016-04-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据和云

View Merge 在安全控制上的变化,是 BUG 还是增强 ?

什么是 View Merge View Merge 是 12C 引入的新特性,也是一种优化手段。当查询中引用了 View 或 inline view 时,优化器...

3247
来自专栏PHP技术

MySQL InnoDB四个事务级别 与 脏读、不重复读、幻读

MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ)。 1).未提交读(READUNCOMMIT...

4206
来自专栏阿杜的世界

【转】Innodb中的事务隔离级别和锁的关系一次封锁or两段锁?事务中的加锁方式参考资料

因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会用到哪些数据,然后全部锁住,在方法运行之后,再全部解锁。这...

633
来自专栏Linyb极客之路

MySQL 表锁和行锁机制

行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整的很惨!不知坑在何方?没事,我来给你们标记几个坑。遇到了可别乱踩。通过本章内容,带你学习My...

652
来自专栏架构之路

悲观锁&乐观锁

最近意外发现之前对悲观锁乐观锁的理解有误,所以重新学习了一下。 1.悲观锁 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事...

2894
来自专栏小灰灰

Mysql之锁与事务

平时的业务中,顶多也就是写写简单的sql,连事务都用的少,对锁这一块的了解就更加欠缺了,之前一个大神分享了下mysql的事务隔离级别,感觉挺有意思的,正好发现一...

43213
来自专栏前端架构

MySQL事务处理

事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的...

401
来自专栏学习有记

包含列的索引:SQL Server索引进阶 Level 5

1002
来自专栏北京马哥教育

LINUX上MYSQL优化三板斧

云豆贴心提醒,本文阅读时间7分钟 现在MySQL运行的大部分环境都是在Linux上的,如何在Linux操作系统上根据MySQL进行优化,我们这里给出一些通用简...

2577
来自专栏架构师之路

浅谈CAS在分布式ID生成方案上的应用 | 架构师之路

近几篇文章聊CAS被骂得较多,今天还是聊CAS,谈谈CAS在一种“分布式ID生成方案”上的应用。 所谓“分布式ID生成方案”,是指在分布式环境下,生成全局唯一I...

3744

扫描关注云+社区