直接访问mysql的BDB存储引擎

我们知道BDB是一种嵌入式的数据库,存取效率比mysql高,但是管理起来没有mysql方便,在分布式应用中同步也是一个问题。

恰好mysql是支持用BDB作为存储引擎的(5.1之后就不直接支持了,因为BDB被oracle收购了),那么能不能让mysql来进行数据管理和同步,而实际应用则绕过mysql直接访问BDB文件呢?

 

尝试了一下:

首先取得mysql 5.0源代码,按如下参数配置

./configure --with-berkeley-db=./bdb 

编译之后启动mysql,建表时加上engine=bdb

此时在mysql的数据目录中可以看见*.db文件了。

用file命令查看,发现文件格式是Berkeley DB (Btree, version 9, native byte-order)

如果用db_dump命令查看,可以发现它与普通的db文件有两处不同:

1. 一般的db文件一个文件中只有一个库,而mysql则生成了两个库,main和status库(如果建表时加了主键之外的索引,则还会生成额外的索引库)

2. mysql生成的db文件,是以表的主索引作为key,用表的整行数据作为value,尤其对于char和varchar的列类型,mysql存储时会在字符串前面加上字符长度。例如"abc"被存储为"/x03abc"

 

对于第一点,可以在dbopen的时候指定一下库名,对于mysql生成的db文件,库名指定为"main"就可以了。

对于第二点,在查询时,需要把待查的key前面加上一个字符串长度,查出结果后,再把结果中的长度信息剥离。

 

这里面仍然存在一些问题,就是表结构的定义并不在db文件中,而在mysql生成的.frm文件里。所以首先你不知道如何拆分字段,其次你不知道表长度的字节是1个字节还是两个字节或者更多。不过这个可以通过约定的方式解决,双方约定好固定的表格式,可以将就一下。

 

但是更棘手的问题来了,做好这些改动后,发现查询某些键值时,能查到结果,而某些键值就查不到结果。

 

原来,问题还是出在字符串前面的长度字节上。一般来说,bdb的应用都使用字符串作为key,但是mysql存储的时候,在字符串前面加了一个字节,这就导致了自定义比较函数的问题。

前面说了,文件格式采用了Btree,那么在插入一个key的时候,是会和根节点比较大小,然后决定去哪一个子树。但是标准的比较大小是逐字节的比较,而在字符串前面加上长度字节后,相当于同长度的字符串会被划到一棵子树上去,也许mysql觉得这样影响检索效率,因此mysql通过自定义的比较函数,在比较字符串时把长度字节去掉之后再比较。而使用标准的DBD的接口,它却是按照标准的比较方式,自然会在很多情况下查找不到。

 

目前还没有想到合适的解决方法,尝试中……

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

问题解决了,在bdb打开文件之前,设置一个自定义的比较函数(DB->set_bt_compare),在比较函数中跳过第一个字节,然后调用strncmp比较剩下的就行了。

 

至此圆满解决直接访问mysql存储引擎问题。

你可能感兴趣的:(UNIX)