注意:以下内容仅为个人研究,受限于水平,不保证结果准确与正确!
数据库版本: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">