深入内核: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 条评论
登录 后参与评论

相关文章

来自专栏idba

insert 语句加锁机制

之前的文章里面总结了很多死锁案例,其实里面有几篇文章对于insert加锁流程表述的不准确,而且微信公众号又无法修改,所以通过本文重新梳理insert...

1323
来自专栏杨建荣的学习笔记

数据清理的遗留问题处理(二)(r6笔记第91天)

之前尝试了历史数据的清理,在逻辑层面清除了数据,可以参见 http://blog.itpub.net/23718752/viewspace-1814000/ 但...

3075
来自专栏北京马哥教育

MySQL 5.7原生JSON格式支持

在MySQL与PostgreSQL的对比中,PG的JSON格式支持优势总是不断被拿来比较。其实早先MariaDB也有对非结构化的数据进行存 储的方案,称为dyn...

3526
来自专栏Hadoop实操

如何使用Phoenix在CDH的HBase中创建二级索引

3462
来自专栏杨建荣的学习笔记

关于date格式的两个案例(r4笔记第96天)

在工作中总是会碰到各种和date相关的问题,一般这种问题都是让人很纠结的。 比如前几天一个朋友和我分享了他关于时间问题的两个案例。 第一个是他在做impdp导入...

3184
来自专栏友弟技术工作室

MySQL优化思路及框架

MySQL优化框架 1. SQL语句优化 2. 索引优化 3. 数据库结构优化 4. InnoDB表优化 5. MyISAM表优化 6. Memory表优化 7...

38110
来自专栏chenssy

在一个千万级的数据库查寻中,如何提高查询效率?

1、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 orderby 涉及的列上建立索引;

1502
来自专栏扎心了老铁

Elasticsearch-sql 用SQL查询Elasticsearch

Elasticsearch的查询语言(DSL)真是不好写,偏偏查询的功能千奇百怪,filter/query/match/agg/geo各种各样,不管你是通过封装...

1.3K4
来自专栏恰童鞋骚年

Hadoop学习笔记—20.网站日志分析项目案例(三)统计分析

  为了能够借助Hive进行统计分析,首先我们需要将清洗后的数据存入Hive中,那么我们需要先建立一张表。这里我们选择分区表,以日期作为分区的指标,建表语句如下...

1362
来自专栏从ORACLE起航,领略精彩的IT技术。

Oracle数据库该如何着手优化一个SQL

3344

扫码关注云+社区

领取腾讯云代金券