Dump Block是否会写Dirty Block

这个问题的起源在于我的上一篇文章-Dump Block是否会读入Buffer Cache,d.c.b.a留言提出了这个问题,dump block会否让刚插入的块写入数据文件呢?

一个有趣的问题,但是我却不知道如何验证,如何查看磁盘上的block内容是一个难点。昨天在Oracle-L邮件列表中提了这个问题,今天就得到Christian Antognini的帮助,提示我可以去使用bbed来查看磁盘块的内容。谢谢Chris,非常好的一个方法。

先放出结论,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号,具体SQL不说了,本例中取得是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(貌似泄漏密码有法律问题,这里就不说了,大家google去吧,可以找到的)

$ 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


BBED> exit

OK,到目前为止我们已经验证了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中的脏数据写回数据文件了。

Update
itpub上的网友oracledba提供了更简单的方法,仍然是v$bh视图,查看v$bh.dirty字段,如果为N表示已经被写入磁盘,如果为Y则表示仍然是脏数据。惭愧,自己却绕了一大圈。

6 thoughts on “Dump Block是否会写Dirty Block

Leave a Reply

Your email address will not be published. Required fields are marked *