首页 | 摘要显示 | 上一页 1 2 3 4 5 下一页

Research Archives

May 23, 2007

解出Oracle日志文件中的Redo SQL语句之三

    初步解决了事务的划分问题. 这得感谢biti_rainy的帮助, 从另一个角度来看, 如果我们的DBA可以一起研究, 估计速度要快得多.

    已经可以用XID这一条线来划分Redo SQL的事务关系了, 来看一下MyLOG的输出例子吧!

LOG> extract start 2 end 6
Start extract redo SQL ...
RBA=0x005e30.00000002.0010,  SCN=0x031f.05c00824,  XID=0x0012.049.000dc2bb,  UBA=0x62c263c4.498b.08
   INSERT INTO OBJ_1044190 (COL1,COL2,COL3,COL4,COL5) VALUES (?,?,?,?,?);

RBA=0x005e30.00000002.0188,  SCN=0x031f.05c00824,  XID=0x000e.018.000daa6f,  UBA=0x3b41c2dd.3bce.2d
   UPDATE OBJ_28267 SET COL84 = ?,COL95 = ?,COL96 = ? WHERE COL84 = ? AND COL95 = ? AND COL96 = ?;

RBA=0x005e30.00000004.0128,  SCN=0x031f.05c00824,  XID=0x0016.04d.0005a421,  UBA=0xb4000fe3.1a0a.0e
   UPDATE OBJ_28267 SET COL3 = ?,COL20 = ?,COL23 = ?,COL34 = ?,COL35 = ?,COL36 = ?,COL39 = ?,COL40 = ?,COL41 = ?,COL45 = ?,COL51 = ?,COL82 = ?,COL83 = ?,COL84 = ?,COL95 = ?,COL96 = ? WHERE COL3 = ? AND COL20 = ? AND COL23 = ? AND COL34 = ? AND COL35 = ? AND COL36 = ? AND COL39 = ? AND COL40 = ? AND COL41 = ? AND COL45 = ? AND COL51 = ? AND COL82 = ? AND COL83 = ? AND COL84 = ? AND COL95 = ? AND COL96 = ?;

RBA=0x005e30.00000006.0028,  XID=0x000e.018.000daa6f,  UBA=0x3b41c2dd.3bce.2d,  Commit Transaction

    上面只是第2个块到第6个块的Redo SQL, 看更多的请下载这个文件. 接下来初步估计有两个任务, 第一个是增加对Oracle 10g的日志文件的支持; 第二个是增加一个数据字典, 解出更直接的Redo SQL语句. 最后肯定留下一堆堆的Bug慢慢研究.

    好象对开发一个类SharePlex逻辑复制软件的信心越来越足了.

May 24, 2007

解出Oracle日志文件中的Redo SQL语句之四

    要想得到更直观的SQL语句, 就得引入数据字典, 这里面主要需要以下三个方面的信息:

  1. Table (Object ID, Table Name, Partition Name)
  2. Column (Segment Column ID, Column Name, Column type)
  3. Key (The columns of primary key or unique index, for updating and deleting)

    在MyLOG中引入了前两个: Table (LOGTAB.TXT)和Column (LOGCOL.TXT)

$ cat LOGTAB.TXT
1,1044190,BP_ADJUSTMENT,PART2
2,28267,CMF,
$ cat LOGCOL.TXT
1,1,ID,VARCHAR2
1,2,PARTITION_KEY,NUMBER
1,3,EXTERNAL_ID,VARCHAR2
1,4,CREATED_BY,VARCHAR2
1,5,CREATION_DATE,DATE
2,69,BILL_FMT_OPT,NUMBER
2,70,BILL_DISP_METH,NUMBER
......

    接下就可以使用这些数据字典信息解出更直观的SQL语句了.

LOG> extract start 2 end 6 table BP_ADJUSTMENT
Start extract redo SQL ...
RBA=0x005e30.00000002.0010,  XID=0x0012.049.000dc2bb
    INSERT INTO BP_ADJUSTMENT ( ID , PARTITION_KEY , EXTERNAL_ID , CREATED_BY , CREATION_DATE ) VALUES (?,?,?,?,?);

RBA=0x005e30.00000006.0028,  XID=0x000e.018.000daa6f,  Commit Transaction

    接下来要做的是将列的具体数值打印出来, 又要开始处理不同的数据类型了, 还好这一部份的代码可以从MyDUL抄过来.

May 25, 2007

解出Oracle日志文件中的Redo SQL语句之五

    Oracle 10g的日志文件格式和8i/9i有很大的不同, 这是早就知道的. 一直没有对10g版本的日志格式没有深入研究, 即然最近更深入地研究了日志格式, 不如将10g的也解决了吧. 昨晚大约花了2个多小时, 终于可以将10g日志文件中的Log Record一个一个地分开来了, 9i中区分Change的那部份代码不能直接用在10g上, 还是花点时间研究一下, 估计也就是保留字节变多了或变少了, 应当不难.

    下面是用Oracle 10g的DUMP LOGFILE命令生成Trace文件, 然后用grep "RBA:"命令整出来的最前五行和最后五行:

REDO RECORD - Thread:1 RBA: 0x000059.00000002.0010 LEN: 0x0070 VLD: 0x05
REDO RECORD - Thread:1 RBA: 0x000059.00000003.0010 LEN: 0x0290 VLD: 0x05
REDO RECORD - Thread:1 RBA: 0x000059.00000004.00b0 LEN: 0x005c VLD: 0x01
REDO RECORD - Thread:1 RBA: 0x000059.00000005.0010 LEN: 0x0290 VLD: 0x05
REDO RECORD - Thread:1 RBA: 0x000059.00000006.00b0 LEN: 0x005c VLD: 0x01
......
REDO RECORD - Thread:1 RBA: 0x000059.00001990.0014 LEN: 0x0118 VLD: 0x01
REDO RECORD - Thread:1 RBA: 0x000059.00001990.012c LEN: 0x05a4 VLD: 0x01
REDO RECORD - Thread:1 RBA: 0x000059.00001993.0100 LEN: 0x00d8 VLD: 0x01
REDO RECORD - Thread:1 RBA: 0x000059.00001993.01d8 LEN: 0x00d8 VLD: 0x01
REDO RECORD - Thread:1 RBA: 0x000059.00001994.00c0 LEN: 0x0060 VLD: 0x01

    下面是用我自已的工具, 输出的最前五行和最后五行, 我也数过总共的行数, 两者是相等的.

RBA=0x000059.00000002.0010, LEN=0x0070 VLD=0x05
RBA=0x000059.00000003.0010, LEN=0x0290 VLD=0x05
RBA=0x000059.00000004.00b0, LEN=0x005c VLD=0x01
RBA=0x000059.00000005.0010, LEN=0x0290 VLD=0x05
RBA=0x000059.00000006.00b0, LEN=0x005c VLD=0x01
......
RBA=0x000059.00001990.0014, LEN=0x0118 VLD=0x01
RBA=0x000059.00001990.012c, LEN=0x05a4 VLD=0x01
RBA=0x000059.00001993.0100, LEN=0x00d8 VLD=0x01
RBA=0x000059.00001993.01d8, LEN=0x00d8 VLD=0x01
RBA=0x000059.00001994.00c0, LEN=0x0060 VLD=0x01

    一个Log Record代表一个数据库的原子操作, 因此这一步是很关键的一大步.

May 28, 2007

解出Oracle日志文件中的Redo SQL语句之六

    终于找到以前的代码为什么不能处理10g日志的原因了, 在10g中, 不知道为什么DML(Layer 11 Opcode 5)跑到了Undo信息(Layer 5 Opcode 1)的前面去了, 而在9i和8i中, 在DML之前绝对是Undo的信息. 下面是在Oracle中DUMP LOGFILE命令生成的一条日志记录:

REDO RECORD - Thread:1 RBA: 0x000059.0000003d.0010 LEN: 0x0270 VLD: 0x0d
SCN: 0x0000.0010ca12 SUBSCN:  1 05/08/2007 13:10:34
CHANGE #1 TYP:2 CLS: 1 AFN:1 DBA:0x0040166a OBJ:732 SCN:0x0000.0010ca0f SEQ:  1 OP:11.5
KTB Redo
......
CHANGE #2 TYP:0 CLS:33 AFN:2 DBA:0x00800089 OBJ:4294967295 SCN:0x0000.00107a7b SEQ:  1 OP:5.2
CHANGE #3 TYP:0 CLS:33 AFN:2 DBA:0x00800089 OBJ:4294967295 SCN:0x0000.0010ca12 SEQ:  1 OP:5.4
CHANGE #4 TYP:0 CLS:34 AFN:2 DBA:0x0080008b OBJ:4294967295 SCN:0x0000.00107a7a SEQ:  5 OP:5.1
ktudb redo: siz: 220 spc: 2266 flg: 0x0012 seq: 0x0067 rec: 0x23
            xid:  0x0009.006.0000008b  
ktubl redo: slt: 6 rci: 0 opc: 11.1 objn: 732 objd: 732 tsn: 0
......

    改了这部份代码后, 程序可以跑下去了, 不这显示的有些信息还是很不正确的, 需要更进一步的去验证各种不同的操作下的日志记录.

解出Oracle日志文件中的Redo SQL语句之七

    对于Delete操作, 取得相应的RowID.

SQL> SELECT ROWID,EMPNO FROM EMP WHERE EMPNO=7934;

ROWID                   EMPNO
------------------ ----------
AAAClAAAEAAAAJ3AAb       7934

SQL> DELETE EMP WHERE EMPNO=7934;

1 row deleted.

Start extract redo SQL ...
RBA=0x000062.00000002.0084,  XID=0x0009.01d.00000090, RID=AAAClAAAEAAAAJ3AAb
    DELETE OBJ_10560 WHERE ROWID = ?;

    对于Update操作, 取得相应的RowID.

SQL> select rowid, empno from emp where empno=7902;

ROWID                   EMPNO
------------------ ----------
AAAClAAAEAAAAJ3AAa       7902

SQL> update emp set ename='fangxin' where empno=7902;

1 row updated.

RBA=0x000063.0000001e.0010,  XID=0x0002.014.00000093, RID=AAAClAAAEAAAAJ3AAa
    UPDATE OBJ_10560 SET COL1 = ? WHERE COL1 = ?;

    对于Insert操作, 取得相应的RowID.

SQL> insert into emp (empno, ename) values (9999,'Fangxin');

1 row created.

SQL> select rowid, empno from emp where empno=9999;

ROWID                   EMPNO
------------------ ----------
AAAClAAAEAAAAJ3AAA       9999

RBA=0x000064.0000001d.0010,  XID=0x0004.015.0000008f, RID=AAAClAAAEAAAAJ3AAA
    INSERT INTO OBJ_10560 (COL1,COL2) VALUES (?,?);

    不过还有Array Insert/Delete和Direct Insert这三种操作类型需要搞定, 说不定10g中还有Array Update这样的一种类型.

上一页 1 2 3 4 5 下一页

当前分类: Research

Creative Commons License
本站版权: 共用创作 CC
署名-非商业性-相同方式分享
本站基于MT-3.36免费版
(©)版权所有, 2004 - 2008, www.AnySQL.net, 保留所有权利.
MSN: loufangxin(a)msn.com, Mail: anysql(at)126.com/support(at)iamdba.com, Skype ID:anysql