oracle还原txt,oracle数据库特种恢复技术(五)--redo篇

本帖最后由 ubotutwin 于 2012-2-1 10:06 编辑

oracle数据库特种恢复技术(五)--redo篇

作者:谢浩

这里的bs选择512是根据oracle软件redo的block尺寸,redo文件的block size不同于数据文件,而是与os单次io的块大小像匹配的,在linux、aix、windows中默认一次io是512字节,hp ux中默认是1024字节。Linux系统可以通过fdisk命令查看os blocksize。这个block size会在redolog的第一个块的偏移20位置用4字节存储(来自Dissecting the Redo Logs)Oracle这样设计的目的是为了尽量保证redo写入的安全性,保证io异常时不会有“切块”的情况发生,因为真正保证数据库数据的并不是数据文件,而是重做日志。(但是如果物理存储设备带有缓存,还是不能避免会有部分数据丢失)dd输出:

00000000h: 01 22 00 00 F8 44 01 00 FB 02 0000 10 80 38 9F ; .

00000010h: 90 03 00 00 0D 05 00 00 35 60 4201 02 00 06 C5 ; ?......5`B....?

00000020h: 00 00 00 00 61 02 C1 02 00 00 0100 02 00 00 00 ; ....a.?........

00000030h: 02 00 00 00 00 63 61 74 34 60 4201 00 00 75 63 ; .....cat4`B...uc

00000040h: 72 70 01 80 02 C1 20 02 C1 1A 2C00 08 03 C2 4C ; r

00000050h: 46 9D D2 2D 0B 02 01 00 03 00 0000 E6 66 C0 00 ; F澮-........鎓?

00000060h: 0F 60 42 01 00 00 01 00 02 02 73C4 16 00 18 00 ; .`B.......s?...

00000070h: 31 00 13 00 07 00 02 00 00 00 0000 01 00 0D 00 ; 1...............

00000080h: 01 00 AB 0C 01 01 00 00 00 00 0000 05 00 28 00 ; ..?..........(.

00000090h: 29 33 00 00 93 0D 80 00 77 13 3100 E6 66 C0 00 ; )3.

000000a0h: E3 66 C0 00 FA 12 02 01 01 00 0000 2C 01 08 00 ; 鉬??......,...

000000b0h: 00 00 13 01 07 00 00 00 00 00 0000 00 00 00 00 ; ................

000000c0h: 00 00 00 00 36 00 64 00 00 18 0000 00 6C 6F 63 ; ....6.d......loc

000000d0h: 41 47 45 4E 54 5F 53 54 41 54 5553 5F 4D 41 52 ; AGENT_STATUS_MAR

000000e0h: 4B 45 52 28 78 6F 0C 01 16 14 0306 C1 04 1E 37 ; KER(xo......?.7

000000f0h: 59 61 02 C1 41 47 45 4E 54 53 5F4D 41 52 4B 45 ; Ya.罙GENTS_MARKE

00000100h: 44 6F 63 61 30 69 6F 6E 05 02 1900 02 00 FF FF ; Doca0ion......

00000110h: 49 00 80 00 ED 5F 42 01 00 00 0000 02 00 FF FF ; I

00000120h: 04 00 20 00 28 00 15 00 29 33 0000 93 0D 80 00 ; .. .(..

。。。。。。。。。。。。。。。。。。。。。省略。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

其中重要信息如下:

前4个字节为redo标识。

从offset 4起占4字节的是该redoblock的rba:F8 44 01 00。

从offset 12起占1字节是该redoblock中第一个redo record的偏移地址:10(一个字节最多表示到255,因此如果一个redo block中被上一个redo block中的redo record占用超过255字节,则该redo block的剩余空间将不再被使用)。

4、根据上一步骤得到的offset,找到第一个redorecord:90 03 00 00 0D 05 00 00 …………..,其中前4字节90 03 00 00表示该redorecord的长度390,之后的0D是一个叫做VLD的变量,该变量直接决定着redo record header的长度,我一直没有找到该变量和redo record header长度之间的对应关系,但是通过分析得出,最重要的增删改操作(即op为11.*的操作)vld为0D,对应的redo record header长度为68字节,事务相关操作(即op为5.*的操作)vld为05,对应的redo record header长度为68字节。

5、由于该redo record中vld为0D,所以第一个改变向量的物理位置为redo record开始offset 68的位置:

00000054h: 0B 02 01 00 03 00 00 00 E6 66 C000 0F 60 42 01 ; ........鎓?.`B.

00000064h: 00 00 01 00 02 02 73 C4 16 00 1800 31 00 13 00 ; ......s?...1...

00000074h: 07 00 02 00 00 00 00 00 01 000D                ; ...........

改变向量中第1、2个字节是该操作的opcode,0B 02转换为10进制为11 2,表示单行插入操作。(op code代码详细信息后附)。改变向量开始offset 24位置,记录了该改变向量中的记录长度列表:

0000006ch: 16 00 18 00 31 00 13 00 07 00 0200 00 00 00 00 ; ....1...........

0000007ch: 01 00 0D 00 01 00 AB 0C                         ; ......?

该列表中,每个记录的长度占两个字节存储,第一个长度是指列表本身的长度,列表中的存放的长度数值,指的是对应记录的有效长度,在文件中存储的记录的实际长度要在有效长度的基础上向上增加到4的倍数,比如第1、2字节:16 00转换为10进制为22,所以该列表的长度就是24字节,最后两个字节为填充字节,没有实际意义。

将其中列表转换为10进制,并按4字节补齐后为:

18 00 31 00 13 00 07 00 02 00 00 00 00 0001 00 0D 00 01 00

对应

24   52  20   8    4     0   0   4    16    4

长度列表之后就是记录的实际值:

00000084h: 01 01 00 00 00 00 00 00 05 00 2800 29 33 00 00 ; ..........(.)3..

00000094h: 93 0D 80 00 77 13 31 00 E6 66 C000 E3 66 C0 00 ; ?

000000a4h: FA 12 02 01 01 00 00 00 2C 01 0800 00 00 13 01 ; ?......,.......

000000b4h: 07 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 ; ................

000000c4h: 36 00 64 00 00 18 00 00 00 6C 6F63 41 47 45 4E ; 6.d......locAGEN

000000d4h: 54 5F 53 54 41 54 55 53 5F 4D 4152 4B 45 52 28 ; T_STATUS_MARKER(

000000e4h: 78 6F 0C 01 16 14 03 06 C1 04 1E37 59 61 02 C1 ; xo......?.7Ya.?

000000f4h: 41 47 45 4E 54 53 5F 4D 41 52 4B45 44 6F 63 61 ; AGENTS_MARKEDoca

00000104h: 30 69 6F 6E                                     ; 0ion

这部分中,前24字节对应dump文件中的ktb结构体,offset 24开始的52字节对应dump文件中的kdo结构体,kdo结构体中一个重要的变量就是offset20位置的solt变量,该变量记录了update操作对应的行号,该行号对应的是数据行在data block中的行号,也就是rowid中的行号,至此,已经在redolog中获得了update操作所对应的对象id、dba、行号三个信息,根据此三个信息已经可以计算出redo record操作的行的rowid了。继续观察,kdo结构体后紧随的是操作的字段编号,占4个字节:01 00 40 04,这里由于前面信息长度列表里这段信息的长度是1,所以有效数据是01,其后的00 40 04为填充位,无意义。再往后保存的是具体操作的字段的值74 65 73 74 31 00 01 00。

SQL> select dump('test1',1016) fromdual;

DUMP('TEST1',1016)

--------------------------------------------------

Typ=96 Len=5 CharacterSet=ZHS16GBK:74,65,73,74,31

可以看到,和dump函数的输出相吻合,最后3个字节的00 01 00,还是填充位,无意义。

这就是一个update操作最关键的修改数据块的改变向量的全部内容,此后在同一redo record中还有其他操作的改变向量,如op为5.1、5.2是对回滚段的相应修改,都属于事务操作的范畴。

Insert操作与update操作的区别是没有“字段编号”这一部分信息(因为用不到),只有ktb、kdo、字段值这三个部分。

Delete操作则只有ktb、kdo两个部分,直接按照kdo中的slot行号信息,加之前的object号,dba就能定位到要删除的行。

至此,redolog中已经能够解出对数据的操作,只要根据不同的op code就能还原redo sql,在这之后又遇到了一个问题,就是如何界定redo log中哪些记录属于一个事务。对此我做了如下实验,在session a中做一个update操作不提交,然后在session b中再做一个update操作并提交,然后再返回session a中提交事务,这样session a中的事务对应的redo 记录就必然被session b中的事务所分割,这个目的是达到了,但是我始终没有找到session a的redo记录之间的联系,session a的事务的改变向量被分割到多个redo record中,没有任何线索能将其串联。为此,一度陷入僵局。

之后我转换了一种思路:这一部分分析的目的,是在恢复数据之后保证数据的准确性,也就是说,要在人工模拟oracle打开过程之后再模拟oracle的recovery database过程。那么,套用oracle本身的行为模式是良好的选择,即,先将redolog里所有对应start scn之后的redo record全部应用前滚,然后再根据data block上的状态flag进行回滚。也就是说oracle本身在redolog这个环节并不需要界定事务,事务的最终标识是在数据块上的相关锁的产生和清除来界定的。至此redo部分已经可以进行简单的应用,下一步是要根据数据块上的事务标识,通过undo构造一致性块,进一步增加恢复的精确性。

附op code列表(来自网络):

格式:layer: opcode

LAYER的含义:

4 — Block Cleanout

5 — Transaction Management

10 — 索引操作

11 — 行操作

13 — 段[url=]管理[/url]

14 — Extent 管理

17 — 表空间管理

18 — Block Image (Hot Backups)

19 — Direct Loader

20 — Compatibility segment

22 — 本地管理表空间

23 — Block Writes

24 — DDL语句

Layer 1 : Transaction Control - KCOCOTCT

Opcode 1 : KTZFMT

Opcode 2 : KTZRDH

Opcode 3 : KTZARC

Opcode 4 : KTZREP

Layer 2 : Transaction Read -  KCOCOTRD

Layer 3 : Transaction Update -  KCOCOTUP

Layer 4 : Transaction Block -  KCOCOTBK     [ktbcts.h]

Opcode 1 : Block Cleanout

Opcode 2 : Physical Cleanout

Opcode 3 : Single Array Change

Opcode 4 : Multiple Changes to an Array

Opcode 5 : Format Block

Layer 5 : Transaction Undo -  KCOCOTUN     [ktucts.h]

Opcode 1 : Undo block or undo segment header - KTURDB

Opcode 2 : Update rollback segment header - KTURDH

Opcode 3 : Rollout a transaction begin

Opcode 4 : Commit transaction (transaction table update)

- no undo record

Opcode 5 : Create rollback segment (format) - no undo record

Opcode 6 : Rollback record index in an undo block - KTUIRB

Opcode 7 : Begin transaction (transaction table update)

Opcode 8 : Mark transaction as dead

Opcode 9 : Undo routine to rollback the extend of a rollback segment

Opcode 10 :Redo to perform the rollback of extend of rollback segment

to the segment header.

Opcode 11 :Rollback DBA in transaction table entry - KTUBRB

Opcode 12 :Change transaction state (in transaction table entry)

Opcode 13 :Convert rollback segment format (V6 -> V7)

Opcode 14 :Change extent allocation parameters in a rollback segment

Opcode 15 :

Opcode 16 :

Opcode 17 :

Opcode 18 :

Opcode 19 : Transaction start audit log record

Opcode 20 : Transaction continue audit log record

Opcode 24 : Kernel Transaction Undo Relog CHanGe - KTURLGU

Layer 6 : Control File -  KCOCODCF     [tbs.h]

Layer 10 : INDEX -  KCOCODIX     [kdi.h]

Opcode 1 : load index block (Loader with direct mode)

Opcode 2 : Insert leaf row

Opcode 3 : Purge leaf row

Opcode 4 : Mark leaf row deleted

Opcode 5 : Restore leaf row (clear leaf delete flags)

Opcode 6 : Lock index block

Opcode 7 : Unlock index block

Opcode 8 : Initialize new leaf block

Opcode 9 : Apply Itl Redo

Opcode 10 :Set leaf block next link

Opcode 11 :Set leaf block previous link

Opcode 12 :Init root block after split

Opcode 13 :Make leaf block empty

Opcode 14 :Restore block before image

Opcode 15 :Branch block row insert

Opcode 16 :Branch block row purge

Opcode 17 :Initialize new branch block

Opcode 18 :Update keydata in row

Opcode 19 :Clear row’s split flag

Opcode 20 :Set row’s split flag

Opcode 21 :General undo above the cache (undo)

Opcode 22 :Undo operation on leaf key above the cache (undo)

Opcode 23 :Restore block to b-tree

Opcode 24 :Shrink ITL (transaction entries)

Opcode 25 :Format root block redo

Opcode 26 :Undo of format root block (undo)

Opcode 27 :Redo for undo of format root block

Opcode 28 :Undo for migrating block

Opcode 29 :Redo for migrating block

Opcode 30 :IOT leaf block nonkey update

Opcode 31 :Cirect load root redo

Opcode 32 :Combine operation for insert and restore rows

Layer 11 : Row Access -  KCOCODRW     [kdocts.h]

Opcode 1 : Interpret Undo Record (Undo)

Opcode 2 : Insert Row Piece

Opcode 3 : Drop Row Piece

Opcode 4 : Lock Row Piece

Opcode 5 : Update Row Piece

Opcode 6 : Overwrite Row Piece

Opcode 7 : Manipulate First Column (add or delete the 1rst column)

Opcode 8 : Change Forwarding address

Opcode 9 : Change the Cluster Key Index

Opcode 10 :Set Key Links (change the forward & backward key links

on a cluster key)

Opcode 11 :Quick Multi-Insert (ex: insert as select …)

Opcode 12 :Quick Multi-Delete

Opcode 13 :Toggle Block Header flags

Layer 12 : Cluster -  KCOCODCL     [?]

Layer 13 : Transaction Segment -  KCOCOTSG     [ktscts.h]

Opcode 1 : Data segment format

Opcode 2 : Merge

Opcode 3 : Set link in block

Opcode 4 : Not used

Opcode 5 : New block (affects segment header)

Opcode 6 : Format block (affects data block)

Opcode 7 : Record link

Opcode 8 : Undo free list (undo)

Opcode 9 : Redo free list head (called as part of undo)

Opcode 9 : Format free list block (freelist group)

Opcode 11 :Format new blocks in free list

Opcode 12 :free list clear

Opcode 13 :free list restore (back) (undo of opcode 12)

Layer 14 : Transaction Extent -  KCOCOTEX     [kte.h]

Opcode 1 : Add extent to segment

Opcode 2 : Unlock Segment Header

Opcode 3 : Extent DEaLlocation (DEL)

Opcode 4 : Undo to Add extent operation (see opcode 1)

Opcode 5 : Extent Incarnation number increment

Opcode 6 : Lock segment Header

Opcode 7 : Undo to rollback extent deallocation (see opcode 3)

Opcode 8 : Apply Position Update (truncate)

Opcode 9 : Link blocks to Freelist

Opcode 10 :Unlink blocks from Freelist

Opcode 11 :Undo to Apply Position Update (see opcode 8)

Opcode 12 :Convert segment header to 6.2.x type

Layer 15 : Table Space -  KCOCOTTS     [ktt.h]

Opcode 1 : Format deferred rollback segment header

Opcode 2 : Add deferred rollback record

Opcode 3 : Move to next block

Opcode 4 : Point to next deferred rollback record

Layer 16 : Row Cache -  KCOCOQRC

Layer 17 : Recovery (REDO) -  KCOCORCV     [kcv.h]

Opcode 1 : End Hot Backup : This operation clears the hot backup

in-progress flags in the indicated list of files

Opcode 2 : Enable Thread : This operation creates a redo record

signalling that a thread has been enabled

Opcode 3 : Crash Recovery Marker

Opcode 4 : Resizeable datafiles

Opcode 5 : Tablespace ONline

Opcode 6 : Tablespace OFFline

Opcode 7 : Tablespace ReaD Write

Opcode 8 : Tablespace ReaD Only

Opcode 9 : ADDing datafiles to database

Opcode 10 : Tablespace DRoP

Opcode 11 : Tablespace PitR

Layer 18 : Hot Backup Log Blocks -  KCOCOHLB     [kcb.h]

Opcode 1 : Log block image

Opcode 2 : Recovery testing

Layer 19 : Direct Loader Log Blocks - KCOCODLB     [kcbl.h]

Opcode 1 : Direct block logging

Opcode 2 : Invalidate range

Opcode 3 : Direct block relogging

Opcode 4 : Invalidate range relogging

Layer 20 : Compatibility Segment operations - KCOCOKCK  [kck.h]

Opcode 1 : Format compatibility segment -  KCKFCS

Opcode 2 : Update compatibility segment - KCKUCS

Layer 21 : LOB segment operations - KCOCOLFS     [kdl2.h]

Opcode 1 : Write data into ILOB data block - KDLOPWRI

Layer 22 : Tablespace bitmapped file operations -  KCOCOTBF [ktfb.h]

Opcode 1 : format space header - KTFBHFO

Opcode 2 : space header generic redo - KTFBHREDO

Opcode 3 : space header undo - KTFBHUNDO

Opcode 4 : space bitmap block format - KTFBBFO

Opcode 5 : bitmap block generic redo - KTFBBREDO

Layer 23 : write behind logging of blocks - KCOCOLWR [kcbb.h]

Opcode 1 : Dummy block written callback - KCBBLWR

Layer 24 : Logminer related (DDL or OBJV# redo) - KCOCOKRV [krv.h]

Opcode : common portion of the ddl - KRVDDL

Opcode : direct load redo - KRVDLR

Opcode : lob related info - KRVLOB

Opcode : misc info - KRVMISC

Opcode : user info - KRVUSER

备注:该操作不包含undo vector, segment header的修改即使交易回滚,它也不会发生回滚。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值