注意:以下内容仅为个人研究,受限于水平,不保证结果准确与正确!

目的:了解逻辑日志是如何记录信息的;了解使用onlog实用程序
数据库版本:IDS V11.50UC6 for linux ,数据库使用log(buf或者unbuf均可)
使用到的相关表: tt2(
                  id char(10),
                  col1 char(20),
                  col2 integer,
                  col3 char(20),
                  col4 char(50),
                  col5 integer
                 );
               create index ix_tt2 on tt2(id);

    往tt2表中插入/更新/删除记录等操作的同时,informix将记录这一操作,并将其写入逻辑日志文件中。可以通过onlog实用程序读取逻辑日志中的记录,其语法如下: 

500)this.width=500;" width="500">
我们通过onlog -l -n 逻辑日志号 的方式来查看具体的事务信息(为方便查看,建议将逻辑日志移至新日志上,再执行事务操作)

  1,插入操作的逻辑日志记录:往表tt2中插入一条新记录
insert into tt2 values('003','test003',99,'CC003','DDD003',101);
  通过onlog -l -n 逻辑日志号 查看到的逻辑日志记录如下:
500)this.width=500;" width="500">
    其包含4部分操作:BEGIN(事务开始),HINSERT(插入记录),ADDITEM(增加索引记录),COMMIT(提交事务)。
    以HINSERT为例介绍:蓝色框标识了该操作所在逻辑日志中的addr,记录长度len,操作类型type,事务xid,id(?何义未知),与上一操作的链接标识地址link,以及其它操作特有信息;红色框内是具体的信息(16进制,其阅读方法78563412(每2位为1字节),4字节为一组)
    注:各数据库版本的逻辑记录方式可能不一样,但大概含义应是一致的
    当前蓝色框内的信息可知:此操作的逻辑日志记录地址是0xd04c,记录的大小为172字节,操作类型是HINSERT,事务xid为22,该操作是紧随逻辑日志记录地址0xd018记录的操作(BEGIN),HINSERT的对像是partnum为0x300009的表,操作相关的rowid是103等信息;
    红色框内的16进制数解释:
第1组4字节0x000000ac(172的16进制)为len,
第2组4个字节中的前2字节(阅读方式中的3412) 0x0028表示HINSERT操作、后2字节(7856)0x0000表示id 0,
第3-7组未知,
第8组的0x0000d018是链接至上一操作的地址,
第9组0x0015cc53是该操作的时间戳标识(具体如何转换,未知),
第10、11组均是操作对向表的partnum 0x00300009(至于为什么出现2个partnum未知,倾向第11组为当前操作对向partnum。另partnum的解析为123位(即1.5字节)为chunk号,另2.5字节为当前chunk的tblspace编号),
第12组在HINSERT操作时为操作的rowid,即插入的新记录的rowid为0x00000103,
第13-16组未知(猜想应当为位置定位)
第17组开始为HINSERT的记录信息(此时数据读取不按照78563412的方式,而是顺序读取,注意每次截位),对比表结构:前10字节30303320 20202020 2020为char(10)即'003'(不足用空(0x20)填充),然后20字节7465 73743030 33202020 20202020 20202020 2020为char(20)即'test003'(不足位用0x20填充),然后4字节0000 0063为integer值99的16进制形式(int是以16进制保存的),然后20字节4343 30303320 20202020 20202020 20202020 2020为char(20)即'CC003'(不足用0x20填充),然后的50字节4444 44303033 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020为char(50)即'DDD003'(不足用0x20填充),最后的4字节00000065为integer值101的16进制形式。

    在ADDITEM中:
第10、11组为索引的partnum,
第12组为索引所在表的partnum,第13组为索引操作的rowid,
第14、15组未知,
第16组开始10字节(同样不按照78563412的方式)30303320 20202020 2020为索引字段值'003'(不足也用0x20填充),
最后一组的除去数据后的2个字节6e65 表示含义未知。


    2,更新操作的逻辑日志记录:
    SQL为:update tt2 set col1='NEWAAAA' where id='003';(更新的不是索引字段)
500)this.width=500;" width="500">
    前16组4字节的含义一致,
第17组未知,
第18组前2字节0x000a是10的16进制,表示该条记录跳10字节(id char(10))开始更新;后2字节0x0008是8的16进制,表示更新的长度是8个字节
第19-20组中的8字节74657374 30303320即'test003'(补空0x20),是更新前的记录,
第21-22组中的8字节4e455741 41414120即'NEWAAA'(初空0x20),是更新后的记录。

    说明:若是同时更新多个字段,类似18-22组的记录将重复出现。另:由于使用是的默认的page锁,update更新时,只更新发生变化的相应的字节,而不是更新整个字段或者整条记录,如上:字段为char(20),但只更新了其中的8个字节。

    3,删除记录的逻辑日志记录
      SQL:delete from tt2 where id='003';
500)this.width=500;" width="500">
    在HDELETE操作中,
前16组4字节组的含义与HINSERT中的一致,
第17组开始为所有删除记录的信息,格式与HINSERT格式一致;

    在DELITEM操作中,
格式与ADDITEM操作中的格式完全一致,最后一组的最后2字节含义未知。


另附:IDS V9.40UC4W4上的插入操作逻辑日志记录
500)this.width=500;" width="500">

 



02-02 19:45