日期:2014-05-16  浏览次数:20427 次

Oracle dirty block的一些探讨(一)
今天刚吃完骨头煲,回到家已是21:30分。由于昨天和今天针对Oracle dirty block做了一些测试,得到了一些结果。于是想把测试过程记录一下,以备后忘。

Oracle dirty block指的是buffer cache中发生过变化且没有刷新到datafile。Oracle block在block head会记录其发生变化时的scn,
也就是说Oracle block在buffer cache更改时也会赋予Oracle当前的scn(如果目前Oracle current scn为1000,此时block发生变化,Oracle会将1000写入block head,这在上篇blog中也有所涉及)。
本文要探讨主要有2个方面:
1、Oracle  block刷到数据文件时,是否有做判断?
(1)如果block在buffer cache中未发生变化,执行alter system flush buffer_cache时是否也会将此block刷新至数据文件?
(2)如果block在buffer cache中发生了变化(也就意味着dirty block),执行alter system flush buffer_cache是否也会将此block刷新至数据文件?
     如果会刷新至数据文件,当磁盘的block scn大于buffer cache中block scn时,刷出动作是否也会进行?
(3)在rac情况下,block刷新至数据文件是否有区别?
2、alter system checkpoint和alter system flush buffer_cache有什么区别?
首先探讨第一种情况:
如果block在buffer cache中未发生变化,执行alter system flush buffer_cache时是否也会将此block刷新至数据文件?
创建业务用户zhoul,并创建测试表格zhoul
SQL> conn zhoul/zhoul    
Connected.
SQL> create table zhoul (i int,name varchar(20));

Table created.

SQL> insert into zhoul values(1,'aaa');

1 row created.

SQL> insert into zhoul values(2,'bbb');

1 row created.

SQL> insert into zhoul values(3,'ccc');

1 row created.

SQL> commit;

Commit complete.
执行全量checkpoint,确保变化块写入数据文件。
SQL> alter system checkpoint;

System altered.
利用dbms_rowid函数获取表格数据对应的数据文件号和block号
SQL> col file# for 999
SQL> col block# for 99999
SQL> set linesize 300
SQL> select  dbms_rowid.ROWID_RELATIVE_FNO(rowid) file#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#,i,name from zhoul;

FILE# BLOCK#          I NAME
----- ------ ---------- --------------------
    7  15511          1 aaa
    7  15511          2 bbb
    7  15511          3 ccc
   

SQL> select name from v$datafile where file#=7;

NAME
--------------------------------------------
/oradata/mcstar/zhoul01.dbf
以aaa列为例,将其转化为16进制之后是616161
SQL> select dump('aaa',16) from dual;

DUMP('AAA',16)
----------------------
Typ=96 Len=3: 61,61,61
利用bbed find字符串功能,定位到行aaa在block 15511偏移量位置8185之后开始存储,共占用3个字节。
[ora10g@mcprod admin]$ bbed filename=/oradata/mcstar/zhoul01.dbf blocksize=8192 password=blockedit mode=edit
BBED> find /c aaa
File: /oradata/mcstar/zhoul01.dbf (0)
Block: 15511            Offsets: 8185 to 8191           Dba:0x00000000
------------------------------------
61616105 067757

<32 bytes per line>

将其改变为zzz字符串,注意这是利用bbed在物理级别修改,Oracle 在buffer cache中并未修改,所以Oracle依旧认为block 15511状态为clean。
BBED> modify /c zzz
Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: /oradata/mcstar/zhoul01.dbf (0)
Block: 15511            Offsets: 8185 to 8191           Dba:0x00000000
------------------------------------
7a7a7a05 067757

<32 bytes per line>

BBED> sum apply
Check value for File 0, Block 15511:
current = 0x9976, required = 0x9976

BBED> exit

如果此时查询zhoul业务表格,可以看到aaa依然存在,并没有出现我们所期望的zzz列,这是因为aaa列依旧在buffer cache中。

SQL> select * from zhoul;

         I NAME
---------- --------------------