使用Visual C++ 2005编译Oracle Berkeley DB
1 前言
Oracle Berkeley DB 是行业领先的可嵌入开源数据库引擎,它为开发人员提供了无需管理的快速、可靠的本地持久性。它是一个直接链接到您应用程序的库。您的应用程序进行简单的函数调用,而不是向远程服务器发送消息,从而消除了客户端-服务器体系结构的性能损耗。 它消除了 SQL 查询处理的开销,从而使应用程序按可预测的访问模式更快地运行。它提供了事务和恢复,用于高并发的锁定,多进程和多线程, 冷热备份,以及用于高可用性应用程序的单主复制。在提供强大功能的同时, 它还具有强大的可配置性, 使得开发人员能够控制它行为的众多方面。
Visual C++ 2005是Windows 平台上最为流行的企业级C/C++编译器,能够在windows平台上产生高效的二进制代码。Visual C++ 2005是Visual Studio 2005的重要组成部分,其安装包含在Visual Studio 2005的安装中,并且其与其他语言的编译器共用一个集成开发环境(IDE)。
本文介绍了如何在Windows上用VC++2005 编译Oracle Berkeley DB 4.7.25 版本。
2 下载Oracle Berkeley DB
Oracle Berkeley DB 可以从此处下载: http://www.oracle.com/technology/global/cn/software/products/berkeley-db/db/index.html

点击Berkeley DB 4.7.25.NC.zip,由于本文描述的是如何从源代码编译出Berkeley DB,故而不选择下载Windows安装程序。下载完成后,解压该文件,解压后进入db-4.7.25.NC, 我们可以发现该文件夹的内容:

3 编译
进入build_windows目录,我们可发现该目录下有一个工程文件(.dsw)和很多的项目文件(.dsp),这里我们选择使用工程文件Berkeley_DB.dsw:
打开Microsoft Visual Studio 2005的IDE, 选择菜单->File->Open->Project/Solution,打开build_windows目录下的Berkeley_DB.dsw文件:

打开后,会提示要求进行project文件的格式转换,选择”Yes To All”:

转换后, 选择编译类型(本文是Debug x86 Win32),鼠标右键单击build_all, 选择build,就开始了编译过程:

build_all编译默认会编译Berkeley DB 静态库、动态库以及一系列的工具程序和示例程序。
编译完成后,可以看到build_windows底下多了一个Debug目录,进入Debug目录,我们可以看到编译出来的文件:

4 运行示例程序
ex_access是Oracle Berkeley DB自带的一个示例程序, 该程序将用户输入的字符串作为关键字(key),将字符串倒置作为数据(data),而后将此键值对存入BerkeleyDB数据库。 当用户键入exit时,该程序将显示数据库的内容, 而后退出:

5 总结
在Windows上用Visual C++2005编译Berkeley DB是比较容易的,读者如果出现了什么编译上的问题,可以与我交流。 在后续章节中,我还将介绍命令行的编译方法, 以及使用现今流行的Code::Blocks编译Oracle Berkeley DB的方法。
我在2003上编译出错呢,请协助解答,谢谢。此外,我以前是oracle dba工作,现在想用内存数据库,想选择这个。
能不能提供一下你的出错信息?
谢谢,已经好了,编译类型选择错误。此外,有关于源码的学习资料吗?谢谢!
Hi hotDB,
请浏览Berkeley DB在Oracle Technology Network(OTN)的官方网站:www.berkeleydb.com。 在官网我们提供了很多的文档,白皮书,客户案例等。
如果你在使用中有进一步的问题,欢迎发到BDB的官方论坛。我们会在那里回答你的。
谢谢。
错误:无法打开文件”libdb47.lib“;
无法打开包括文件”tcl.h“等
几十处错误
在你的IDE中指定正确的头文件路径和库文件路径。另外你不需要包含tcl.h的。你是做编译DB的示例程序吗?
你好, 如果按照本文的步骤一步步来, 即只编译build_all, 是不会有这种错误提示的. 因为build_all不包含对tcl库的编译, 这对java也成立.
请问, 你是否需要编译tcl呢?
想要研究一下Berkeley DB C++代码,该从哪里入手呢?谢谢
你好,我请教一个问题,我在vs2008上编译完成,但是在测试doc文档中的一些代码时,发现:C++语言的可以过去,但是c语言的都过不去,总是出现一些奇怪的提示。
如:
#include
…
Db db(NULL, 0); // Instantiate the Db object
u_int32_t oFlags = DB_CREATE; // Open flags;
try {
// Open the database
db.open(NULL, // Transaction pointer
“my_db.db”, // Database file name
NULL, // Optional logical database name
DB_BTREE, // Database access method
oFlags, // Open flags
0); // File mode (using defaults)
// DbException is not subclassed from std::exception, so
// need to catch both of these.
} catch(DbException &e) {
// Error handling code goes here
} catch(std::exception &e) {
// Error handling code goes here
} 测试可以通过,但是与它对应的c语言版本的
#include
…
DB *dbp; /* DB structure handle */
u_int32_t flags; /* database open flags */
int ret; /* function return value */
/* Initialize the structure. This
* database is not opened in an environment,
* so the environment pointer is NULL. */
ret = db_create(&dbp, NULL, 0);
if (ret != 0) {
/* Error handling goes here */
}
/* Database open flags */
flags = DB_CREATE; /* If the database does not exist,
* create it.*/
/* open the database */
ret = dbp->open(dbp, /* DB structure pointer */
NULL, /* Transaction pointer */
“my_db.db”, /* On-disk file that holds the database. */
NULL, /* Optional logical database name */
DB_BTREE, /* Database access method */
flags, /* Open flags */
0); /* File mode (using defaults) */
if (ret != 0) {
/* Error handling goes here */
}却出现这个提示:
DB->put: method not permitted before handle’s open method。
c和c++版的对应代码都有类似的情况:c++通得过,c通不过。
我在用vs6.0时,也发现这个错误,但是自从我把buildwindows\release下的libdb47.dll拷贝到bin文件夹下后,已经解决问题了。现在转到vs2008下面发现这个办法不灵了。。。。。
不知何故。
希望你帮我看一下,感激不尽!!!
你好, 基本上,这个错误的是因为:机器上装有多个版本的BDB, 运行时链接的库和编译期的库不同.
建议首先检查一下编译使用的BDB库文件的位置和版本,然后检查一下程序运行时使用的PATH变量, 看看其中是否包含其他位置/版本的BDB的动态链接库.
我原先重装过系统,但是bdb的目录还在,所以我只是添加了系统的path便由6.0转到2008,结果出了以上的问题。今日听君一语,终于决定重装bdb,再重新编译,现在已经解决了。感谢!!!
#include
#include
#include
int main(int argc, char *argv)
{
u_int32_t env_flags = DB_CREATE | DB_INIT_MPOOL;
std::string envHome(“/testEnv”);
DbEnv myEnv(0);
try{
myEnv.open(envHome.c_str(), env_flags, 0);
}
catch(DbException &e){
std::cerr<<”Error openning database environment 1:”<<envHome<<std::endl;
std::cerr<<e.what()<<std::endl;
exit(-1);
}
catch(std::exception &e){
std::cerr<<”Error openning database environment 2:”<<envHome<<std::endl;
std::cerr<<e.what()<<std::endl;
exit(-1);
}
std::cout<<”This operarion is completed…”<<std::endl;
}
上面代码中的envHome怎么设置才能正确生成数据库环境呢?我创建了envHome文件夹也不行。。谢谢!
你好, 鉴于你将环境目录设置为/testEnv, 我想知道一下你是用什么用户来运行该示例程序的, 是root用户还是其他的普通用户? 如果是其他用户, 请确认一下是否该用户可以向/testEnv里面添加文件. 因为正常情况下,打开环境的时候, 会在环境文件夹下创建若干文件.
一般情况下, 用root用户创建的文件夹可以被其他用户读(cd/ls),.但是, 要让普通用户可以往该文件夹放文件, 还需要用chmod设置一下文件夹的mode.
我用的是Windows环境,VS2008,管理员权限,那个路径设置成相对路径就没事儿,可能是由于源代码是在Linux环境下编写的,路径格式不同吧。。
谢谢您的解答!
请问应该如何使用dbenv->set_cachesize 来动态的更改数据库的内存,我尝试过很多方法都不能动态设置
@LongSky
您好, 我们正在研究这个问题, 并将尽快给您答复.
@jeak
我也出现了这个问题,我的解决方法重新编译,我出现的原因是还没有生成成功我就结束了编译,然后重新编译后就出现这个问题。预祝成功
你好,很抱歉很久没给回复。
一般来说,要更改Environment内存,需要首先注意满足以下条件:
A, mutex的最大值需要足够大, 因为如果不够大的话, mutex将被消耗光, 设置/更改将出错。可以用DB_ENV->mutex_set_max来更改此值。
B, Cache的最大值需要足够大, 显然应当要大于你动态更改的最大值。可以用DB_ENV->set_cache_max来设置此值。
而后,在DB_ENV->open的前后,都可以调用DB_ENV->set_cachesize来设置内存的大小,也可以通过DB_ENV->get_cachesize来获得内存的大小。设置的与获得的并非完全一致,二者之间有一些差别,具体解释如下:
1 首次创建环境(即首次产生__db.001等文件):如果在DB_ENV->open之前未调用DB_ENV->set_cachesize来设置大小, 则默认的cachesize是256KB, nchache是1。如果有设置,当设置的cachesize<500MB时, 实际的cachesize大约是设置大小的1.25倍,否则,比实际值大一点点。ncache和设置的相同。创建环境以后,在环境目录下会有ncache个region文件。文件大小(regsize)略大于实际cachesize/ncache,这个大小是不会变化的,以后新增加的region文件也是这么大。
2 更改内存大小:如上,当cachesize<500MB, 则会上浮25%,否则保持原值。变化的流程是:a,如果当前要实际设置的cachesize不需要ncache个region文件,则region文件数目会减少,即ncache减小,并且删除多余的region文件。如果需要更多的region文件,则ncache会增加,同时创建更多的region文件。 否则region文件和ncache维持不变。
3 判断是否需要ncache的数目很简单,基本依据是:cachesize大小与ncache-2个总容量, ncache-1个总容量, 以及ncache个总容量的比较关系。
4 get_cachesize获得的gigabyte和cachesize是在创建时候设置的值,而ncache反映的实际的ncache,即region文件的数目。ncache的数目也可以通过对环境目录下的region文件数目分析出来,因为那些文件大小一样, 具体值如1所言。
在这点上, API实际功能和文档上可能有些不一致,后续将证实此情况。
参考: http://www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/frame_main.html
您好,我用的是VC++6.0编译的D:\DB\db-4.8.26\examples_cxx\getting_started 文件夹下的MyDb.dsw 出现以下报错:
——————–Configuration: MyDb – Win32 Debug——————–
Linking…
MSVCRTD.lib(crtexe.obj) : error LNK2001: unresolved external symbol _main
Debug/MyDb.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
MyDb.exe – 2 error(s), 0 warning(s) vc++”settings”和“options”都做了修改 可以编译像“hello world”