64位照片解析_Oracle RedoLog-解析关键问题,VLD,XID

上篇文章,简单分析了 RedoLog 字节格式。接下来,介绍下解析过程中关键问题的处理,主要包括:如何计算 Record 头长度-VLD如何计算事务的 XID数值字节的转换逻辑

1. 计算 Record 头长度-VLD

Record 头的长度是根据 VLD 的值得出的,已知的值有:

4f634bdd6c587317ac7199368910b5e6.png

图中每个值的含义是:

  • value= 0:Record 内容无效
  • value= 1:Record 包含 change vectors
  • value= 2:Record 包含已提交的 SCN
  • value= 4:包含依赖 SCN,内部还有其他 SCN
  • value= 8:Record 新的 SCN,此时,SCN 已在此实例的重做日志中精确分配
  • value=16:Record 旧的 SCN,重做日志中,在此点或之前分配的 SCN。可能由另一个实例分配
  • value=32:分配了新的 SCN,确保在按 SCN 排序时,某些块的重做由 inc/seq# 排序

Record 头长度有两种情况:24字节 和 68字节,通常情况下是 24字节,在某些情况下会增加到 68字节。

目前,没有找到明确的资料说明哪些是某些情况。能搜索到的是:只要 VLD 的值中包括了4,长度就是68字节,反之是24字节。包括 4的意思是,比如 VLD: 0x0d,十进制就是 13=8+4+1,长度就是 68;VLD: 0x09,十进制就是 9=8+1,长度就是 24。

仔细分析下这些值的组成,这个逻辑很容易使用位运算来处理!

2. 计算事务 XID

在日志里,事务的开始和结束标志,有可能在一个 Record 中,也有可能分散在不同的 Record 中,提交和回滚的是哪个事务,都是通过 XID 关联起来的。

有些操作能提取到 XID,有些则不能,但是每个操作都会有开始和结束,5.2 和 5.4 两个操作码,下面是这两个操作的 dump 信息:

CHANGE #2 TYP:0 CLS:19 AFN:3 DBA:0x00c00090 OBJ:4294967295 SCN:0x0000.0010c5bb SEQ:3 OP:5.2 ENC:0 RBL:0ktudh redo: slt: 0x0018 sqn: 0x0000033a flg: 0x0012 siz: 108 fbi: 0            uba: 0x00c007a0.009b.40    pxid:  0x0000.000.00000000CHANGE #4 TYP:0 CLS:19 AFN:3 DBA:0x00c00090 OBJ:4294967295 SCN:0x0000.0010c5e6 SEQ:1 OP:5.4 ENC:0 RBL:0ktucm redo: slt: 0x0018 sqn: 0x0000033a srt: 0 sta: 9 flg: 0x2 ktucf redo: uba: 0x00c007a0.009b.41 ext: 2 spc: 640 fbi: 0 

XID 由三部分组成 xid: ..,slt 和 sqn 上面信息都有,主要是 USN 的值,它的全称是 Undo Segment Number,可根据 CLS 的值确定。

CLS 即 Block classes,已知的有:

d740be839bf57af220a77a83d747db65.png

值大于 16 的是保留给 undo segments (撤消段)使用,如图所示,每个 undo segment 都有编号,并且关联两个 CLS,一个用于 undo segment header (就是 5.2 使用);一个用于 undo segment blocks (就是 5.1 使用)。

根据此表对应关系,示例中 CLS:19 对应的 USN=2,所以此次事务的 XID 为 0x0002.018.0000033a,slt 为什么去掉个 0 暂不知原因。

3. 数值字节的转换

关于数值的存储,Oracle 有一个编码方法,先看下数字编码情况:

  • 1-99,以2字节存储,第一个字节指示符为 0xC1,第二个字节为数值本身加1。比如,数字1 被编码为0xC102,2为0xC103
  • 100-9999,存储为 2或3字节,指示符为 0xC2,数字100将是0xC202,而101将是0xC20202,201为0xC20302,301为0xc20402
  • 10000-999999,指示符为 0xC3,数字10000将被存储为0xC302,10001被存储为0xC3020102
  • 1000000-99999999,指示符为 0xC4,数字1000000将被存储为0xC402,1000001被存储为0xC402010102
  • 100000000-9999999999,指示符为 0xC5 以此类推

规则就是:1到99之间的数字为单位数字;数值加1存储;数字末尾每多两个零,指示符加1。

比如 9999=99*100+99=0xC26464, 999999=99*10000+99*100+99=0xC3646464

上篇文章中的数字编码为 0xC20931 解码后 (0x09-1)*100+(0x31-1)=848。

4. ROWID 的计算

rowid 是一条记录的唯一标识,存储的是每条记录的实际物理地址。由 18位 64进制数据组成,包含四部分:

  • 数据对象 ID:长度 6,data_object_id,日志中可直接获取
  • 相对文件编号:长度 3,DBA 高10位
  • 块编号:长度 6,DBA 低22位
  • 行编号:长度 3,slot,这个获取有点麻烦,OP11.2 操作码存储在 KDO 结构中

rowid 的四部分采用 Base64 编码,即64进制,由 A~Z, a~z, 0~9, +, /共64个字符表示。其中 A表示0,B表示1,……,a表示26,……,0表示52,……,+表示62,/表示63。

来看一个插入示例:

CHANGE #2 TYP:0 CLS:1 AFN:4 DBA:0x01000213 OBJ:74770 SCN:0x0000.001307b0 SEQ:3 OP:11.2 ENC:0 RBL:0KTB Redo op: 0x02  ver: 0x01  compat bit: 4 (post-11) padding: 0op: C  uba: 0x00c0041d.00ae.1bKDO Op code: IRP row dependencies Disabled  xtype: XA flags: 0x00000000  bdba: 0x01000213  hdba: 0x01000212itli: 1  ispac: 0  maxfr: 4858tabn: 0 slot: 1(0x1) size/delt: 9fb: --H-FL-- lb: 0x1  cc: 2null: --col  0: [ 3]  c2 64 64col  1: [ 1]  62

找出 rowid 的四部分并转成 Base64:

  • object_id:74770=64*64*18+64*16+18,64进制是 AAASQS
  • file_id:0x01000213 转成二进制后高10位是 100 十进制是4,64进制是 004=AAE
  • block_id:0x01000213 转成二进制后低22位是 0000000000001000010011 十进制是 531=64*8+19,64进制是AAAAIT
  • num:slot=0x1 64进制是 001=AAB

所以此次插入的记录rowid是 AAASQSAAEAAAAITAAB。

5. 总结

至此,通过这三篇文章,应该可以从 Redolog 文件中,准确的解析出每个 Record,从 Record 中解析出每个 Change,增删改操作的数据就在这些 Change 内。

默认情况下,INSERT 操作信息就记录在 OP 11.2 中;UPDATE 操作在日志中只是记录有变动的字段信息;DELETE 操作删除的记录信息记录在 undo OP 5.1 中。

在解析过程中还有很多问题要解决,比如一个 Record 中由多个新增删除更新操作,redo 块undo 块如何进行匹配?大字段 blob, clob 如何处理?回滚如何处理等等,总之完善起来那是相当麻烦的事~~

查看原文,请点击 了解更多

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值