数据块dump详解及大小表扫描过程

查找对象的数据块、RDBA、dump trace文件

SCOTT@ prod>select deptno,rowid,
  2  dbms_rowid.rowid_relative_fno(rowid) file#,
  3  dbms_rowid.rowid_block_number(rowid) block#,
  4  dbms_rowid.rowid_row_number(rowid) row#,
  5  dbms_rowid.rowid_object(rowid) object# from dept1;

    DEPTNO ROWID                   FILE#     BLOCK#       ROW#    OBJECT#
---------- ------------------ ---------- ---------- ---------- ----------
        10 AAAU/WAAEAAAAITAAA          4        531          0      85974
        20 AAAU/WAAEAAAAITAAB          4        531          1      85974
        30 AAAU/WAAEAAAAITAAC          4        531          2      85974
        40 AAAU/WAAEAAAAITAAD          4        531          3      85974
        50 AAAU/WAAEAAAAIXAAA          4        535          0      85974

查询数据块的RDBA
SCOTT@ prod>select dbms_utility.make_data_block_address(4,535) from dual;

DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS(4,535)
-------------------------------------------
                                   16777751
知道数据块RDBA,查询数据位置
SCOTT@ prod>SELECT dbms_utility.data_block_address_file(16777751) file#,
  2  dbms_utility.data_block_address_block(16777751) block# from dual;

     FILE#     BLOCK#
---------- ----------
         4        535

dump出数据结构
SYS@ prod>alter session set events 'immediate trace name buffer level 16777751';

SYS@ prod>oradebug setmypid
SYS@ prod>alter system dump datafile 4 block 535;
SYS@ prod>oradebug tracefile_name;
/u01/app/oracle/diag/rdbms/prod/prod/trace/prod_ora_8395.trc
dump文件详解

*** 2014-02-25 15:18:12.359
Start dump data blocks tsn: 4 file#:4 minblk 531 maxblk 531
Block dump from cache:
Dump of buffer cache at level 4 for tsn=4, rdba=16777747
BH (0x2abfabe4) file#: 4 rdba: 0x01000213 (4/531) class: 1 ba: 0x2abbe000
  set: 3 pool 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 526,28
  dbwrid: 0 obj: 85974 objn: 85974 tsn: 4 afn: 4 hint: f
  hash: [0x3e28d250,0x3e28d250] lru: [0x2abfad64,0x2abfabbc]
  ckptq: [NULL] fileq: [NULL] objq: [0x2abfad7c,0x2abfabd4]
  st: XCURRENT md: NULL tch: 3
  flags: only_sequential_access
  LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]
  cr pin refcnt: 0 sh pin refcnt: 0
Block dump from disk:
buffer tsn: 4 rdba: 0x01000213 (4/531)
scn: 0x0000.005c0958 seq: 0x02 flg: 0x04 tail: 0x09580602
frmt: 0x02 chkval: 0x71f5 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
。。。
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn 0x0000.005c0956
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x03   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
bdba: 0x01000213
data_block_dump,data header at 0x60207c

解读trace文件
BH (0x2abfabe4) file#: 4 rdba: 0x01000213 (4/531) class: 1 ba: 0x2abbe000
--BH (0x2abfabe4) ,这是BH的HASH值
--rdba: 0x01000213 (4/531)rdba就是rowid中的相对文件号rfile#+block#块号。
--class: 1 对应X$BH.class --表示buffer header对应block的类型,1=data block。  --其他值见后面
--ba: 0x2abbe000  对应X$BH.BA,这是BUFFER中block address,是块在内存中的物理地址。
  set: 3 pool 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 526,28
-- set: 3:对应X$BH.STATE,CR(3)=作为一致性读镜像的数据块      --其他值见后面
  dbwrid: 0 obj: 85974 objn: 85974 tsn: 4 afn: 4 hint: f
--obj: 85974,对应X$BH.OBJ ,也就是块上数据在哪个对象里-- dba_objects.DATA_OBJECT_ID
  hash: [0x3e28d250,0x3e28d250] lru: [0x2abfad64,0x2abfabbc]
--对应x$bh.nxt_hash x$bh.prv_hash这里用链表,指出下一个及前一个BH的HASH值。如果这个hash chain上只有一个bh,则这里的前一个及后一个BH的hash值都是此BH
--对应x$bh.nxt_repl x$bh.prv_repl这里用链表,指出下一个及前一个BH的在LRU链上HASH值。
  ckptq: [NULL] fileq: [NULL] objq: [0x2abfad7c,0x2abfabd4]
--ckptq: [NULL] 在检查点队列上的HASH值,这里为空
--fileq: [NULL] 在文件队列上的HASH值
--objq: [0x22ff8054,0x24839390] 对应x$bh.oq_nxt x$bh.oq_prv .对象队列HASH值
--objaq:对应x$bh.aq_nxt x$bh.aq_prv.辅助对象队列HASH值
  st: XCURRENT md: NULL tch: 3
--st: XCURRENT  对应x$bh.state    ----见下表
--tch: 3  对应X$BH.TCH,Touch的缩写,表示一个Buffer的访问次数--不过不是绝对,3秒内访问同一块,TCH不增加。与此相关的一个字段是:$BH.tim --Touch Time
  flags: only_sequential_access
--flags: only_sequential_access   对应x$bh. FLAG
  LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]
--LSCN: [0x0.0] HSCN: [0xffff.ffffffff] 修改时的SCN--如记录有修改时的SCN,可以转换此十六进制为SCN进行对比
--LRBA: [0x0.0.0] 应该是最低REDO BYTE ADDRES,[0x0.0.0]对应日志号,块号,第几字节起。也可能会有HRBA ,recovery rba 。
  cr pin refcnt: 0 sh pin refcnt: 0
Block dump from disk:
buffer tsn: 4 rdba: 0x01000213 (4/531)
--这个块的TSN 表空间号和RDBA
scn: 0x0000.005c0958 seq: 0x02 flg: 0x04 tail: 0x09580602
--SCN直接转换为用to_number函数转换为10进制就是数据库内查出的SCN了,是这个块的状态改变时的SCN
frmt: 0x02 chkval: 0x71f5 type: 0x06=trans data
--type:0x06(表/索引块)
--frmt:  0x01(v7)  0x02(v8)

数据块的事物槽

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn 0x0000.005c0956
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x03   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
-------------------------------------------------------------------------------------------
附:
flag中,每位代表如下含义:
bit bit
0 buffer_dirty 14 stale
1 notify_after_change 15 deferred_ping
2 mod_started 16 direct_access
3 block_has_been_logged 17 hash_chain_dump
4 temp_data 18 ignore_redo
5 being_written 19 only_sequential_access
6 waiting_for_write 20 prefetched_block
7 multiple_waiters 21 block_written_once
8 recovery_reading 22 logically_flushed
9 unlink_from_lock 23 resilvered_already
10 down_grade_lock 25 redo_since_read
11 clone_being_written 29 plugged_from_foreign_db
12 reading_as_CR 30 flush_after_writing
13 gotten_in_current_mode 
class:表示buffer header对应block的类型:
            1=data block,                   9=2nd level bmb,     
            2=sort block,                   10=3rd level bmb,    
            3=save undo block,              11=bitmap block,     
            4=segment header,               12=bitmap index block,
            5=save undo header,             13=unused,           
            6=free list,                    14=undo header,      
            7=extent map,                   15=undo block   
state:
0, FREE, no valid block image
1, XCUR, a current mode block, exclusive to this instance 正在被当前的instance独占。
2, SCUR, a current mode block, shared with other instances正在被当前的instance共享
3, CR, a consistent read (stale) block image 一致读
4, READ, buffer is reserved for a block being read from disk 正在从磁盘上读取块
5, MREC, a block in media recovery mode  处于介质恢复模式
6, IREC, a block in instance (crash) recovery mode处于实例恢复模式

0,'free',1,'xcur',2,'scur',
3,'cr', 4,'read',5,'mrec',
6,'irec',7,'write',8,'pi', 9,'memory'
10,'mwrite',11,'donated', 12,'protected',  
13,'securefile', 14,'siop',15,'recckpt',
 16, 'flashfree',  17, 'flashcur', 18, 'flashna'
lru_flag
SYS@ prod>select distinct(lru_flag) from x$bh;

  LRU_FLAG
----------
         6
         4
         8
         0
X$BH.lru_flag 为0,对应在产LRU的冷端头--DSI中有。也可以通过DUMP buffer cache,搜索BH中LRU的值来计算0状态时BH的位置。
X$BH.lru_flag 为2,对应:lru-flags: moved_to_tail  在LRU热端
X$BH.lru_flag 为8,对应:lru-flags: hot_buffer  在LRU热端 ---据说还有一种状态是9,也是在热端。
X$BH.lru_flag 为4,对应:lru-flags: on_auxiliary_list
X$BH.lru_flag 为6,对应:lru-flags: moved_to_tail on_auxiliary_list  在辅助LRU

SYS@ prod>select  lru_flag,tch,BA,decode(state,0,'free',1,'xcur',2,'scur',3,'cr', 4,'read',5,'mrec',6,'irec',7,'write',8,'pi', 9,'memory',10,'mwrite',11,'donated', 12,'protected',  13,'securefile', 14,'siop',15,'recckpt', 16, 'flashfree',  17, 'flashcur', 18, 'flashna') status from x$bh where FILE#=4 and DBABLK=531;

  LRU_FLAG        TCH BA       STATUS
---------- ---------- -------- ----------
         0          3 2ABBE000 xcur
SYS@ prod>select file#,block#,status from v$bh where objd=85974;

     FILE#     BLOCK# STATUS
---------- ---------- ----------
         4        532 xcur
         4        535 cr
         4        535 xcur
         4        530 cr
         4        530 xcur
         4        533 xcur
         4        531 xcur
         4        534 xcur
cache buffer中LRU、LRUW列表

数据块逻辑读过程:
1.前台进程发出查询语句select deptno from bys.test;
2.根据DBA计算HASH值,根据HASH值找到相应的Hash bucket
3.获取CBC LATCH,如获取失败,则将产生:latch:cache buffers chains
4.在CBC LATCH保护下,服务器进程扫描hash chain,查找是否有所需BH
5.如查找到所需BH,将在Buffer Header上加buffer pin锁(这里是读操作所以是共享锁(找到BH时的锁常见有:当前读锁、一致读锁或修改锁),如获取buffer pin失败(比如正在X模式申请S模式),会产生buffer busy waits等待),并根据BH中指定的块在内存中实际地址,读取buffer,并将结果返回前台进程。读取完毕(纳秒级)后,将再次获取CBC LATCH,释放buffer pin锁,再释放CBC LATCH。
大表的全表扫表过程:

大小表的界限是:_small_table_threshold,此参数中的VALUE 是数据块个数。
大表的全表扫描只使用辅助LRU,其块的TCH为1。这样做不对主LRU上的块进行冲击,同时也方便大表中块的重用。此时如有其它用户语句需要从辅助LRU上查找可用buffer,直接可以使用,节约时间。
_small_table_threshold的值在数据库启动的时候自动配置成BUFFER数量的2%。
数据块与小表的物理读过程:

1.大表全表扫描只使用辅助LRU,此时TCH=1,如此后再有对大表中某一行的读取,TCH=2。此时如果SMON进程醒来,或者遇到有其它物理读扫描到些块,会将此TCH=2的块移到主LRU热端头,lru_flag=8,TCH清零。
2.正常读取时,在辅助LRU上找到可用块后会将其移动到主LRU的冷端头,lru_flag=0,tch=1
3.主LRU的热端尾的块被挤出到冷端头时,TCH不变。
4.主LRU冷端最尾的块被挤出时,如TCH>=2时,也会被移动到热端头,TCH=0;
5.flush buffer_cache后查询,块都是TCH=0。SMON进程移动主LRU上TCH<2块到辅助LRU上时不清零。
(主LRU与辅助LRU上块的比例大致是:75%,25%。在数据库刚启动或者刚flush buffer_cache后所有buffer都在辅助LRU上。SMON进程每3秒会从主LRU冷端尾开始扫描,将TCH<2的块移动到辅助LRU,以此维护主LRU与辅助LRU上块的比例。主LRU上冷端和热端上块的比例是50%,这由隐含参数:_db_percent_hot_default决定的--默认值就是 50)
6.如果未查找到所需BH,将发生物理读。服务器进程将从磁盘上的相应数据文件中读取所需块,并将此块读入buffer cche中。
7.将块读入buffer cache中时,如何找到一个可以使用的buffer呢?下面步骤进行一步步解析。
8.首先在辅助LRU的最尾端向前查找可用buffer,TCH<2的块可以被重用。
9.如果辅助LRU最尾端的块是TCH<2的块,则将直接使用此块,并将其移动到主LRU的冷端头。
同时也会根据此块的DBA进行HASH,查找相应的HASH BUCKET,将此块加入到对应的HASH CHAIN上,并对BH中的相应信息进行修改(如对应X$BH中的LRU_FLAG,NXT_HASH、BA等字段的具体值)--此过程也需要相应的CBC LATCH /buffer pin锁的获取释放等。再把数据块的值返回前台进程,此时物理读就完成了。
10.如果辅助LRU最尾端的块是TCH>=2的块,则首先将此块移动到主LRU的热端头,同时TCH清零;然后在在辅助LRU上继续向前查找,直到找到可用的块---TCH<2。之后的过程和步骤9中的就一样了。(SMON每三秒时,服务器进程扫描空闲BUFFER时;都会把辅助LRU中TCH大于等于2的移到主的热端头)
11.如果在辅助LRU上搜索完毕扔未找到可以使用的块,则将从主LRU的冷端尾开始搜索。
12.如果主LRU最尾端的块是TCH<2的块,则将直接使用此块,并将其移动到主LRU的冷端头,TCH为1。如是TCH>=2的块,则将其移动到热端头,TCH清零。如果是脏块,则将其移动到主LRUW上。依此规则向前搜索查找可用块。(SMON每3秒,从主LRU冷端查找TCH小于2的非脏块到辅助LRU确保辅助LRU中有可用BUFFER)
13.如果从主LRU最尾端向前搜索了40%(隐含参数_db_block_max_scan_pct,11GR2后好像不太一样了?)还未找到可用块,则将触发DBWR写LRUW上的脏块--(CKPTQ队列的写不涉及LRUW,只有DBWR会写LRUW上脏块,并且写的是LRUW上的全部脏块-每三秒醒来也要全部写出LRUM上所有块才会休眠。写LRUW上脏块的步骤是:DBWR进程写时或者SMON进程每三秒醒来时(LRUW进程不像辅助LRUW那样,非DBWR进程也允许访问),会将主LRUW上的一部分脏块移动到辅助LRUW,然后在辅助LRUW上排序、写入磁盘;然后再从主LRUW上移动下一批,直到写出完毕再次进入睡眠。并且在DBWR写出过程中,会产生free buffer waits),写出后的buffer将重新挂载到辅助LRU上并变为可用。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值