今天来和大家简单谈一下rba ,rba = redo byte address 。
讲到rba,这里涉及到了几点需要大家提前预知,即controlfile header,ckpt process 与 dbwn process , dirty buffer 。
先来看一下RBA的构成:
它由3部分组成,4byte+4byte+2byte分别为 logfile sequence number ,logfile block number,byte offsetinto the block ,即redo 序列号,redo block 号,以及偏移量。
并且全部使用16进制。
例如:rba= 0x000024.000011bd.0010
seq#=0x000024=36
blk#=0x000011bd=4541
ofs#=0x0010=16
接下来说一下instance recovery
这里的Checkpoint position 其实就是cache low rba, End of redo thread就是最后一个on-disk rba。
大家都知道实例恢复的时候需要从cache low rba 到 on-disk rba , lowrba 与 on-disk 全部存储在控制文件里面,on-diskrba可以简单的理解为是 lgwr 最后写日志文件的地址。那么cachelow rba是如何而来呢?
cache low rba 其实就是ckpt进程每3秒写入到controlfileheader 上面的rba 。
大家知道 ckpt 分为三种,即 database check points ,Tablespace and datafilecheckpoints和Incremental checkpoints。这里和第三种checkpoints有关。增量检查点的存在是为了防止在发生日志切换的时候,写出大量的dirty block 到disk上面,它每3秒会监控一下dbwn写出block的情况,并且写到controlfile header里面(不包括datafile header)。
这里有几点需要注意:
1. dbwn写出 dirtyblock 是使用一个叫做ckpt queue的双向链表来维护的,按照lrba的顺序写出dirty block 到 disk 上面。
2. 每个dirty block 上面都有一个lrba ,并且有一个指向ckpt queue的指针。
3. dbwn触发条件,请详见concepts。
好,下面我们用实验说话:
1.
先取出几个块的数据
01:57:02 dex@FAKE> select * from
01:58:10 2 (
01:58:10 3 selectdbms_rowid.rowid_relative_fno(substr(rowid,1,15)||'AAA') as file# ,
01:58:10 4 dbms_rowid.rowid_block_number(substr(rowid,1,15)||'AAA') as blk#,
01:58:10 5 max(t.id),max(t.name)
01:58:10 6 from dex.t
01:58:10 7 group by substr(rowid,1,15)
01:58:10 8 )
01:58:10 9 where rownum < 4 ;
FILE# BLK# MAX(T.ID) MAX(T.NAME)
---------- ---------- ---------- --------------------
4 446 37949 name
4 447 38433 name
4 442 39401 name
看一下
x$bh
02:02:17 sys@FAKE> select dbablk ,lrba_seq,lrba_bno,flag from x$bh b where file#=4 and dbablk in (442,446,447);
DBABLK LRBA_SEQ LRBA_BNO FLAG
---------- ---------- ---------- ----------
442 0 0 524288
447 0 0 524288
446 0 0 524288
看一下当前的
cache low rba
和
ondisk rba
02:02:21 sys@FAKE> selectcplrba_seq,cplrba_bno,cplrba_bof,cpodr_seq,cpodr_bno,cpodr_bof,cphbt,cpodt fromx$kcccp where indx=0 ;
CPLRBA_SEQ CPLRBA_BNO CPLRBA_BOF CPODR_SEQ CPODR_BNO CPODR_BOF CPHBT CPODT
---------- ---------- ---------- -------------------- ---------- ---------- --------------------
37 10567 0 37 13157 0 791349660 08/15/2012 02:02:02
2.
更新数据
02:07:16 sys@FAKE>update dex.t set name='aaaa'where id=37949 ;
1 row updated.
02:10:46 sys@FAKE>update dex.t set name='ssss'where id=38433 ;
1 row updated.
02:10:46 sys@FAKE>update dex.t set name='dddd'where id=39401 ;
1 row updated.
02:10:48 sys@FAKE>commit ;
Commit complete.
3.
查看一下各种状态
状态为脏数据
02:10:51 sys@FAKE> select dbablk ,lrba_seq,lrba_bno,flag from x$bh b where file#=4 and dbablk in (442,446,447);
DBABLK LRBA_SEQ LRBA_BNO FLAG
---------- ---------- ---------- ----------
442 37 14429 33554433
447 37 14429 33554433
446 37 14429 33554433
现在的
cache low rba
为
14104
02:10:56 sys@FAKE> selectcplrba_seq,cplrba_bno,cplrba_bof,cpodr_seq,cpodr_bno,cpodr_bof,cphbt,cpodt fromx$kcccp where indx=0 ;
CPLRBA_SEQ CPLRBA_BNO CPLRBA_BOF CPODR_SEQ CPODR_BNO CPODR_BOF CPHBT CPODT
---------- ---------- ---------- -------------------- ---------- ---------- --------------------
37 14104 0 37 14437 0 791349830 08/15/2012 02:10:51
4.
再来更新一下
442
块的内容
02:12:00 sys@FAKE>update dex.t setname='bfsdff' where id=39401 ;
1 row updated.
02:10:10 sys@FAKE>commit ;
Commit complete.
可以看到
flag
变了,但是这个
block
的
lrba
确没有变,这是因为对于一个
dirty block
只会有一个
lrba
。直到这个
dirty block
被写出到
disk
为止。
002:12:36 sys@FAKE> select dbablk ,lrba_seq,lrba_bno,flag from x$bh b where file#=4 and dbablk in (442,446,447); DBABLK LRBA_SEQ LRBA_BNO FLAG
---------- ---------- ---------- ----------
442 37 14429 33554441
447 37 14429 33554433
446 37 14429 33554433
我们可以看到这时的
cache low rba
已经为
14398
这说明
14398
以前的
dirty block
已经被写出到
disk
上。
02:12:55 sys@FAKE> selectcplrba_seq,cplrba_bno,cplrba_bof,cpodr_seq,cpodr_bno,cpodr_bof,cphbt,cpodt fromx$kcccp where indx=0 ;
CPLRBA_SEQ CPLRBA_BNO CPLRBA_BOF CPODR_SEQ CPODR_BNO CPODR_BOF CPHBT CPODT
---------- ---------- ---------- -------------------- ---------- ---------- --------------------
37 14398 0 37 14491 0 791349872 08/15/2012 02:12:13
再来看一下
buffer
中的内容。
lrba
的内容已经被清掉了。
02:15:47 sys@FAKE> select dbablk ,lrba_seq,lrba_bno,flag from x$bh b where file#=4 and dbablk in (442,446,447);
DBABLK LRBA_SEQ LRBA_BNO FLAG
---------- ---------- ---------- ----------
442 0 0 35651584
447 0 0 35651584
446 0 0 35651584
关于实例恢复:
实例恢复是从
cache low rba
到
ondisk rba
的,但是
ckpt
确实每
3
秒检查一次
dbwn
写出的状态,所以就有可能出现
dirty block
已经写出到
disk
上,但是却没有记录到
controlfile header
上面。这个时候,实例恢复还是从上一次记录的
cache low rba
开始恢复。
下面有个实例恢复的
trace
信息,见附录
2
。
使用
dumplogfile
命令查看
dirty block
当前
rba
。具体请看下面的附录
1
。
附录
1
查看
dirtyblock
当前
rba
sys@FAKE> set time on
02:34:21 sys@FAKE>oradebug setmypid
Statement processed.
02:34:24 sys@FAKE>oradebugtracefile_name
/u01/apps/
oracle/diag/rdbms/fake/fake/trace/fake_ora_7405.trc
02:34:28sys@FAKE> selectl.sequence#,l.group#,l.status,f.status,member fromv$log l , v$logfile f wherel.group#=f.group# ; SEQUENCE# GROUP#STATUS STATUS---------- ---------------------------------
MEMBER
------------------------------------------------------------------------------------------------------------------------------------------------------
36 3 INACTIVE
/u01/apps/oracle/oradata/fake/redo03.log
35 2 INACTIVE
/u01/apps/oracle/oradata/fake/redo02.log
37 1 CURRENT
/u01/apps/oracle/oradata/fake/redo01.log
02:35:14 sys@FAKE>alter system dumplogfile '/u01/apps/oracle/oradata/fake/redo01.log'02:35:28 2 dba min 4 44202:36:38 3 dba max 4 442 ;
System altered.
02:36:42 sys@FAKE>!vi/u01/apps/oracle/diag/rdbms/fake/fake/trace/fake_ora_7405.trc
主要片段
REDO RECORD - Thread:1RBA:
0x000025.0000389a
.0010 LEN: 0x01e0 VLD: 0x0dSCN: 0x0000.0017af70SUBSCN: 1 08/15/2012 02:12:13
rba=seq#37 blk#14490
附录
2
实例恢复片段
23:51:08 sys@FAKE> selectcplrba_seq,cplrba_bno,cplrba_bof,cpodr_seq,cpodr_bno,cpodr_bof,cphbt,cpodt fromx$kcccp where indx=0 ;
CPLRBA_SEQ CPLRBA_BNO CPLRBA_BOF CPODR_SEQ CPODR_BNO CPODR_BOF CPHBT CPODT
---------- ---------- ---------- -------------------- ---------- ---------- --------------------
36 7988 0 36 8068 0 791347039 08/14/2012 23:47:34
实例恢复
trace
关键性信息
THREAD #1 - status:0x2flags:0x0 dirty:25low cacherba
0x24.1f34.0) ondisk rba
0x24.1f84.0)on disk scn:0x0000.0017453f 08/14/201223:47:34resetlogs scn:0x0000.000ce1bd 07/08/201213:36:03heartbeat: 791347199 mountid: 4210244756
0x24.1f34.0=seq#36blk#7988
0x24.1f84.0=seq#36blk#8068
转自:http://www.itpub.net/thread-1706088-1-1.html