要了解REDO的内容的话,首先我们必须了解两个概念:改变向量和重做记录。
1)、改变向量(change vector)
改变向量表示对数据库内某一数据块所作的一次变更。其中包括变更的数据块的版本号、事务操作代码、变更从属数据块的地址以及更新后的数据。
2)重做记录(redo record)
重做记录通常由一组改变向量组成,是改变向量的集合,代表一个数据库的变更(INSERT、UPDATE、DELETE等操作),构成数据库变更的最小恢复单位。例如,一个update的重做记录包括相应的回滚段的改变向量和相应的数据库的改变向量等。
先拿insert,update玩玩。
先看insert
SQL> create table test(id number,name varchar2(20),sal number);
Table created.
SQL> select dbms_flashback.get_system_change_number() from dual;
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER()
-----------------------------------------
8961794
SQL> select group#,status from v$log;
GROUP# STATUS
---------- ----------------
1 INACTIVE
2 INACTIVE
3 CURRENT
4 INACTIVE
5 INACTIVE
SQL> select group#,member from v$logfile where group#=3;
GROUP#
----------
MEMBER
--------------------------------------------------------------------------------
3
/oracle/app/oradata/cloudsea/redo03.log
2
/oracle/app/oradata/cloudsea/redo031.log
SQL> insert into test values(1,'test1',2000);
1 row created.
SQL> commit;
Commit complete.
SQL> select dbms_flashback.get_system_change_number() from dual;
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER()
-----------------------------------------
8961826
SQL> alter system dump logfile '/oracle/app/oradata/cloudsea/redo03.log' scn min 8961794 scn max 8961826;
System altered.
SQL> select spid from v$process where addr =
2 (select paddr from v$session where sid =(
3 select distinct sid from v$mystat));
SPID
------------
22156
在udump中找到名字为22156的用户跟踪日志。在其中找到了刚才insert的重做记录(可能就有人有疑问了,日志里面这么多重做记录,你这么知道这段就是insert的重做记录呢,下面我们一起研究为什么是这段哦,呵呵),下面分析分析这个重做记录:
SQL> select object_id,object_name from all_objects where object_name='TEST' and wner='SYS';
OBJECT_ID OBJECT_NAME
---------- ------------------------------
60206 TEST
我们看到第二段数据块改动向量中的obj恰好是60206,而OP:11.2标识是insert改动,所以由此我们可以知道就是这段日志哦。
第一段:
RBA(REDO BYTE ADDRESS):指定了该重做记录在重做日志文件中的位置,它的格式是:重做日志序列.重做块号.此块中的偏移量
LEN:重做记录的长度,16进制表示
SCN:这个RBA对应的SCN
SUBSCN:这个SCN中的SEQNO,也就是说同一个SCN可能有多个REDO RECORD产生,如果不同的重做记录SCN相同,那么SUBSCN递增,在数据库前滚应用REDO时,必须按ORDER BY SCN,SUBSCN的顺序来应用。
第二段:
这个重做记录中的第一个改动向量,是数据块的改动向量。
TYP:块类型,0-正常的,1-新块,2-延迟记录等
CLS:block类型,除了undo block/undo header类型外,与x$bh.class相同
1 — Data Block
2 — Sort Block
3 — Deffered Undo Segment Blocks
4 — Segment Header Block (Table)
5 — Deffered Undo Segment Header Blocks
6 — Free List Block
7 — Extent Map Blocks
8 — Space Management Bitmap Blocks
9 — Space Management Index Blocks
10– Unused
11+2r — Segment Header for undo segment r
12+2r — Data blocks for undo Segment r
AFN:文件编号
DBA:此改动向量对应的数据块地址
OBJ:OBJECT_ID,可以在DBA_OBJECTS里查到对应的对象信息。
:这个改动向量能应用到的数据块的版本号
OP:操作类型。它指出这个改动向量做了什么内部调用。每个OP的改动向量结构是不一样的。11.2对应的应该是INSERT ROW PIECE。
XID:事务ID,它对应一个UBA(这个改动向量里有个UBA地址的),这个UBA作用在于构建CR BLOCK,通过它可以定位要回滚BLOCK信息的起始位置。xid=Undo.Segment.Number+Transaction.Table.Slot.Number+Wrap
BDBA:如果是REDO改动向量,那么就是数据块地址。如果是UNDO的改动向量,则是UNDO关联的数据块地址,而不是UNDO关联的UNDO块地址
HDBA:该块所在的段头块地址
SIZE/DELT:REDO的增量
COL:实际的数据插入。
第三段:
这是重做记录中的第二个改动向量,注意:我这里说的顺序并不是ORACLE操作的实际顺序,实际顺序是按SCN和SEQNO来的。这是一个回滚段头块的改动向量,记录了COMMIT前事务表的更改。前面重复的东西就不再介绍了。
UBA:对应的回滚块地址,这个回滚段头UBA指向了事务中最后的一个UNDO BLOCK,UBA=Undo.Segment.dba+ubasqn+ubarec,例如此段中的uba: 0x00800591.0e1a.11,0e1a对应第五段中的seq: 0x0e1a,11对应第五段中的rec: 0x11。0x00800591这个回滚段的dba地址通过转换可以得到回滚段前镜像的UBAFIL,UBABLK ,以下是转换的过程:
0x00800591转换成2进制
0000 0000 1000 0000 0000 0101 1001 0001
前十位组合在一起是文件号,后面的是块号
0000 0000 10 00 0000 0000 0101 1001 0001
文件号 块号
所以文件号是2,块号是1425。
PXID:回滚故障事务所产生的事务,可以V$FAST_START_TRANSACTIONS 中查询到,通过XID列联接V$FAST_START_SERVERS 可以查到对回滚进行处理的并行查询服务器的数量。
第四段:
这是重做记录中的第三个改动向量,这又是一个回滚段头块的改动向量,记录的是COMMIT后事务表的更改。
STA:9就是提交标记
第五段:
这是一个UNDO块的改动向量
KDO Op code: DRP ,DRP是DROP ROW PIECE的意思
SLOT:我们看CHANGE#1使用SLOT槽来指示要回滚删除的行号。这个SLOT与CHANGE#1里的那个是一样的哦。这样INSERT的UNDO记录非常小,只要记录SLOT就知道了,它的操作正好是DELETE。
ITL事务槽:Interested Transaction List(ITL)
ITL内容包括:
xid---Transaction ID
Uba---Undo Block Address
Lck---Lock Status
小结一下, INSERT的时候,产生了一个重做记录,这个重做记录中生成了四个改动向量,我来排下序:
第一、UNDO SEGMENT HEADER中,回滚段事务表的改动 CHANGE#2
第二、回滚段数据块的改动,CHANGE#4
第三、数据块的改动,CHANGE#1
第四、UNDO SEGMENT HEADER中,事务提交时对回滚段事务表的改动。
UNDO SEGMENT HEADER中的事务表,记录了回滚段上的事务信息,它对应一个UBA,这个UBA指向事务表中最后一个UNDO BLOCK。而在数据块的改动中,我们看到了数据块头中对应有一个事务ID(XID),它是由XIDUSN(回滚段号)、XIDSLOT(回滚段槽号)、XIDSQN(序列号)组成。一个XID对应有一个UBA,而这个UBA的作用在于构建CR BLOCK(一致性读块),通过它可以定位要回滚的BLOCK信息的起始位置。在数据块中,有一个ITL事务槽是指向UNDO SEGMENT HEADER的。
下面就op的值含义做个总结。
(op=5.2) 表示:修改undo header中事务表信息
(op=5.1)表示:修改undo block信息
(op=11.2) 表示:记录数据块的单行insert
(op=11.3) 表示:记录数据块的delete
(op=11.5)表示:记录数据块的单行update
(op=11.9)表示:记录数据块的数组update
(op=5.4)表示: commit后,修改undo header中事务表信息
而对于带索引块的单行插入,会有以下几个操作:
1、UNDO块的改动向量(SCN:1260304 SEQ1)
2、回滚段头事务表的改动向量(SCN:1260305 SEQ1)
3、表块的改动向量(SCN:1260415 SEQ2)
索引叶块插入的改动向量(SCN:1260415 SEQ2)
4、回滚段头块的改动向量,记录COMMIT后事务表的更改(SCN:1260424 SEQ1)
索引的UNDO块改动向量(SCN:1260424 SEQ1)
我们看到带索引的DML,新增了索引块和索引UNDO块的REDO。
下面我们看下update
SQL> alter system switch logfile;
System altered.
SQL> select group#,status from v$log;
GROUP# STATUS
---------- ----------------
1 ACTIVE
2 CURRENT
3 INACTIVE
4 INACTIVE
5 INACTIVE
SQL> select group#,member from v$logfile where group#=2;
GROUP#
----------
MEMBER
--------------------------------------------------------------------------------
2
/oracle/app/oradata/cloudsea/redo02.log
2
/oracle/app/oradata/cloudsea/redo021.log
SQL> select dbms_flashback.get_system_change_number() from dual;
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER()
-----------------------------------------
9052896
SQL> update test set sal=4000 where id = 1;
1 row updated.
SQL> commit;
Commit complete.
SQL> select dbms_flashback.get_system_change_number() from dual;
DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER()
-----------------------------------------
9052918
SQL> alter system dump logfile '/oracle/app/oradata/cloudsea/redo02.log' scn min 9052896
2 scn max 9052918;
System altered.
查看跟踪日志:
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25964700/viewspace-704261/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/25964700/viewspace-704261/