[转]为PHP增加Berkeley DB的原生API
FreeBSD/Linux/Server January 6th, 2009 538 ViewsPHP中默认对BerkeleyDB的支持是通过DBA系列函数来实现的。由于DBA系列函数是对一系列key-value数据库的抽象,因此丧失了很多BerkeleyDB的原生API支持。
(看了下php_dba的C代码中db4部分的实现,的确是很简单……)
其实BerkeleyDB的发行包中是包含了对BerkeleyDB原生API支持的PHP模块的(php_db4)。但是,抱怨一下,由于 SleepyCat(现在是Oracle了)的文档只写了“支持PHP4”,所以我一直以为这个原生API模块只能运行在PHP4上……今天Google 了一下,很少有人提及PHP5下的BDB原生API问题。于是试了一把。
果然OK。。。
方法与php_db4的INSTALL文件中所说的一样,不过要注意的几点是:
1. (这个INSTALL文件有提及)在绝大多数的Unix类系统下,编译BDB时默认都是会尝试使用libpthread的。但是如果编译PHP时没有打开pthread支持(configure里的–with-tsrm-pthreads的注释是Use POSIX threads (default),默认应该是打开的了吧?),则需要关闭BDB对libpthread的支持。方法是在BDB的configure的时候加上:–with-mutex=x86/gcc-assembly,或者编译PHP的时候加上–with-experimental-zts(这个选项至少在编译PHP 5.2.1的时候是没有,有关的一个是–enable-maintainer-zts,不过这个选项后边注明了:Enable thread safety - for code maintainers only!!注:ZTS是Zend Thread Safety的缩写,一组zend引擎的宏);
2. 我编译php_db4的过程中,make的时候遇到了错误,说找不到exception.h。解决方法如下CPPFLAGS=-DHAVE_CXX_STDHEADERS ./configure
–with-db4=/usr/local/BerkeleyDB.4.5
–with-db4=/usr/local/BerkeleyDB.4.5
然后再make,就一切OK了;
3. 奇怪的是,在CLI下如果使用原生API,会冒出个Segmentation fault的错误。。。网上有人说,在CLI下会出这个错误,但是在WEB环境下就一切正常!解释和解决方法还没找到,继续找ing…
———————————————–
找到Segmentation fault的原因了,这里强烈感谢杨建同学的帮助!
详细描述一下:
系统:Fedora Core 6 running on VMWare Workstation
BerkeleyDB版本:4.5,编译时未加任何参数
测试程序很简单:就一行:
<?php
// File: test.php
$a = new Db4Env();
?>
在前边所述的情况下,执行php test.php,就会看到一行恼人的Segmentation fault
现在我们来看看发生了什么:
# strace php test.php
execve("/usr/local/bin/php", ["php", "/home/lycboy/test.php"], [/* 23 vars */]) = 0
brk(0) = 0×9a41000
brk(0)
……(以下省略很多行)
open("/usr/local/BerkeleyDB.4.5/lib/tls/i686/sse2/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/tls/i686/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/tls/i686/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/tls/i686", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/tls/sse2/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/tls/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/tls/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/tls", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/i686/sse2/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/i686/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/i686/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/i686", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/sse2/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib", {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
open("/usr/local/mysql/lib/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=50238, …}) = 0
mmap2(NULL, 50238, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f32000
close(3) = 0
open("/usr/lib/libdb_cxx-4.3.so", O_RDONLY) = 3
stat64("/usr/local/BerkeleyDB.4.5/lib/tls/i686/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/tls/i686/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/tls/i686", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/tls/sse2/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/tls/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/tls/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/tls", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/i686/sse2/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/i686/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/i686/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/i686", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/sse2/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib/sse2", 0xbfc11b14) = -1 ENOENT (No such file or directory)
open("/usr/local/BerkeleyDB.4.5/lib/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/local/BerkeleyDB.4.5/lib", {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
open("/usr/local/mysql/lib/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/libdb_cxx-4.3.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)
fstat64(3, {st_mode=S_IFREG|0644, st_size=50238, …}) = 0
mmap2(NULL, 50238, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f32000
close(3)
open("/usr/lib/libdb_cxx-4.3.so", O_RDONLY) = 3
……(以下省略很多行)
— SIGSEGV (Segmentation fault) @ 0 (0) —
+++ killed by SIGSEGV +++
Process 4168 detached
+++ killed by SIGSEGV +++
Process 4168 detached
# _
看到上边标记的一行了么?实际上使用了/usr/lib/libdb_cxx-4.3.so!
这是安装FC6的时候所带的db4-devel库。可是应该链接的是4.5版的BDB C++库才对呀!
find了一下libdb_cxx*,没找到4.5。看来默认并不编译C++库。于是回去,重新编译:
#
# ../dist/configure –enable-cxx
# make && make install
现在,在bdb目录/lib下能够找到libdb_cxx.4.5.so了:)
然后开始重新编译php_db4模块:
# ../php_db4/
(如果是第一次编译,别忘了执行phpize)
# make clean(如果不是第一次编译,别忘了这个)
现在,我们需要指定以下使用的库(我习惯bash,用csh的XD们相应改一下)
# export LD_LIBRARY_PATH=/usr/local/BerkeleyDB.4.5/lib/
# export LD_RUN_PATH=/usr/local/BerkeleyDB.4.5/lib/
# CPPFLAGS=-DHAVE_CXX_STDHEADERS LDFLAGS=-L/usr/local/BerkeleyDB.4.5/lib ./configure –with-db4=/usr/local/BerkeleyDB.4.5
注意配置参数变化的部分
然后,make && make install
再试验一下我们的例子——OK了:)
验证一下,再次strace:
……
open("/usr/local/BerkeleyDB.4.5/lib/libdb_cxx-4.5.so", O_RDONLY) = 3
……
没错儿了:)

Recent Comments