在oracle里,假如我们去dump一个快,我们通常都会用到alter system dump datafile XXX block XXX,当你执行上述命令的时候,oracle会这么做:
首先判断一下你要dump的这个block是否在buffer cache中,如果在,则buffer cache中这个block的内容就会是你的dump文件中的内容,这时候oracle不会产生实际的物理I/O去相应的datafile中读这个block(所以这里有可能会存在不一致的情况,这种情况用BBED非常容易模拟);如果不在,oracle会产生实际的物理I/O去相应的datafile中读这个block,读到的内容就是你的dump文件中的内容,注意此时oracle不会把读到的那个block缓存在buffer cache中。
那么问题来了,oracle里有没有纯粹的不产生物理I/O,而只是从buffer cache中dump缓存在其中的block的内容的方法呢?
答案是有的,如下的两条语句联合使用就可以达到上述目的了:
alter session set events 'immediate trace name set_tsn_p1 level <tablespace#+1>';
alter session set events 'immediate trace name buffer level <RDBA>';
这里的tablespace#是指ts$中的ts#
RDBA需要自己做一下转换,比如
SQL> exec sys.cdba('01000020','H');
.
The file is 4
The block is 32
这里datafile number是4,用10位长度的bit表示就是0000 0001 00;
这里block number是32,用22位长度的bit表示就是 00 0000 0000 0000 0010 0000,所以这里拼起来的8位长度byte表示的RDBA就是01000020。
我们来看一个实际的例子:
SQL> oradebug setmypid
Statement processed.
SQL> alter session set events 'immediate trace name set_tsn_p1 level 5';
Session altered.
SQL> alter session set events 'immediate trace name buffer level 0x01000020';
Session altered.
SQL> oradebug tracefile_name;
/u01/app/oracle/admin/ipratest/udump/ipratest_ora_6771106.trc
$ cat /u01/app/oracle/admin/ipratest/udump/ipratest_ora_6771106.trc
/u01/app/oracle/admin/ipratest/udump/ipratest_ora_6771106.trc
Oracle Database
......省略显示部分内容
Dump of buffer cache at level 10 for tsn=4, rdba=16777248
BH (
set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0
dbwrid: 0 obj: 51147 objn: 51147 tsn: 4 afn: 4
hash: [700000084fa03d8,7000000bc9292e0] lru: [700000084fa0458,70000006cf
lru-flags: on_auxiliary_list
ckptq: [NULL] fileq: [NULL] objq: [NULL]
st: FREE md: NULL tch: 0
flags:
Buffer contents not dumped
这里我们可以看到,因为0x01000020不在buffer cache中,所以dump出来的内容为空。
SQL> select empno,ename,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid) location from scott.emp;
EMPNO ENAME LOCATION
----- ---------- --------------------------------------------------------------------------------
7369 SMITH 4_32
7498 CUIHUA 4_32
......省略显示部分内容
7934 MILLER 4_32
12 rows selected
SQL> oradebug setmypid
Statement processed.
SQL> alter session set events 'immediate trace name set_tsn_p1 level 5';
Session altered.
SQL> alter session set events 'immediate trace name buffer level 0x01000020';
Session altered.
SQL> oradebug tracefile_name;
/u01/app/oracle/admin/ipratest/udump/ipratest_ora_3747844.trc
$ cat /u01/app/oracle/admin/ipratest/udump/ipratest_ora_3747844.trc
/u01/app/oracle/admin/ipratest/udump/ipratest_ora_3747844.trc
Oracle Database
......省略显示部分内容
*** SESSION ID:(398.232) 2010-02-20 16:36:35.170
Dump of buffer cache at level 10 for tsn=4, rdba=16777248
BH (
set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0
dbwrid: 0 obj: 51147 objn: 51147 tsn: 4 afn: 4
hash: [
ckptq: [NULL] fileq: [NULL] objq: [
st: XCURRENT md: NULL tch: 1
flags: only_sequential_access
LRBA: [0x
buffer tsn: 4 rdba: 0x01000020 (4/32)
scn: 0x0008.aa1369dd seq: 0x02 flg: 0x06 tail: 0x69dd0602
frmt: 0x02 chkval: 0x4021 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x07000000664DE000 to 0x07000000664E0000
7000000664DE000
......省略显示部分内容
7000000664DFFE0 49544805
7000000664DFFF0
Block header dump: 0x01000020
Object id on Block? Y
seg/obj: 0xc7cb csc: 0x08.aa1369db itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1000019 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x
0x02 0x0001.023.00001129 0x020005e7.
data_block_dump,data header at 0x7000000664de064
===============
tsiz: 0x
hsiz: 0x2e
pbl: 0x7000000664de064
bdba: 0x01000020
76543210
flag=--------
ntab=1
nrow=14
frre=2
fsbo=0x2e
fseo=0x1aa7
avsp=0x1d88
tosp=0x1d88
0xe:pti[0] nrow=14 offs=0
0x12:pri[0] offs=0x1b
0x14:pri[1] offs=0x1aa7
0x16:pri[2] sfll=9
......省略显示部分内容
0x
block_row_dump:
tab 0, row 0, @0x1b
tl: 38 fb: --H-FL-- lb: 0x0 cc: 8
col 0: [ 3] c2
col 1: [ 5] 53 4d 49 54 48
col 2: [ 5] 43
col 3: [ 3] c2 50 03
col 4: [ 7] 77 b4
col 5: [ 2] c2 0b
col 6: *NULL*
col 7: [ 2] c1 15
......省略显示部分内容
end_of_block_dump
BH (
set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0
dbwrid: 0 obj: 51147 objn: 51147 tsn: 4 afn: 4
hash: [700000084fa03d8,
lru-flags: on_auxiliary_list
ckptq: [NULL] fileq: [NULL] objq: [NULL]
st: FREE md: NULL tch: 0
flags:
Buffer contents not dumped
11G的dump已经包含了dump from cache和dump from disk两部分了。
我觉得alter system dump datafile x block y;
无论file# x block y 是否在 buffer cache中,这个动作都是从物理文件中获取数据,并且似乎不会放入buffer_cache中。
10.2.0.4
SYS@MYDB10G AS SYSDBA>select tch
2 from x$bh
3 where dbarfil = 4
4 and dbablk = 14056;
未选定行
SYS@MYDB10G AS SYSDBA>alter system dump datafile 4 block 14056;
系统已更改。
SYS@MYDB10G AS SYSDBA>select tch
2 from x$bh
3 where dbarfil = 4
4 and dbablk = 14056;
未选定行
我不是已经在上述文章中提到“注意此时oracle不会把读到的那个block缓存在buffer cache中”吗?如果这个block已经在buffer cache里,oracle不会产生实际的物理I/O去相应的datafile中读这个block的。验证的方法就是你在库open的时候先select一下这个block,接着用BBED online改一下这个block,然后再dump,如果dump的结果是BBED改过后的值,则证明产生了实际的物理I/O,反之就证明没有产生实际的物理I/O。