首页 > Berkeley DB, Emily Fu > BDB C# API初探

BDB C# API初探

2009年10月14日 傅翠云

Net framework源代码开放算是微软在开源社区开天辟地了,C#作为其主要载体,承载着微软无限希望。这万里长征的第一步,却引起了开源社区的不少涟漪。作为开源社区首屈一指的数据库,BDB借着东风,乘胜追击,推出了其C# API。在此,笔者抛砖引玉,简述C# API如何使用。

1. 概述

BDB C# API建立在BDB C API的基础上,通过上层C#的接口,调用BDB内核。BDB C# API基于.Net Framework 2.0及以上版本,可运行于32位和64Windows平台,实例开发环境为Microsoft Visual Studio 2005及以上版本。除了特别说明,下文中提到的编译或运行操作均在Microsoft Visual Studio2005中进行。

BDB C# API打包在BDB源代码里(最新代码可从http://www.oracle.com/technology/software/products/berkeley-db/index.html下载)。在BDB的代码中,BDB C# API的代码主要分布于以下目录:

l <db-4.8.24>\csharpC# API源代码;

l <db-4.8.24>\libdb_csharpdb.idb_csharp_wrap.cC# APIC API方法之间的映射;

l <db-4.8.24>\test\scr037C# API的测试代码;

l <db-4.8.24>\examples_csharp:使用C# API的实例。

通过编译BDB C# API,在<db-4.8.24>\build_windows\AnyCPU\{release, debug}将得到相应的C#库。

BDB C# API支持绝大多数BDB的功能。此外,BDB C#API接口清晰明了,并提供了C#用户专用的参考的使用手册,源代码,测试及多种实例。因此,使用BDB C# API,可以轻松地实现一个功能完备的数据库应用。

2. 编译

编译BDB C# API本身需要BDB C的动态库。在BDB的源代码中,C# API的解决方案已包含了BDB C工程,因此,编译该解决方案,无须另外编译和指定BDB C动态库。

进入BDB主目录 <db-4.8.*>\下的build_windows目录,打开该目录下的C# API的解决方案BDB_dotNet.sln。打开后,浏览解决方案,如图1所示。
图片1

该解决方案文件包含10个工程,其工程名,内容和相对主目录db\的工程文件路径分别是:

工程名

内容

工程文件路径

db

C API

build_windows\db.vcproj

db_csharp

SWIG生成的封装文件

build_windows\db_csharp.vcproj

db_dotnet

C# API

csharp\db_dotnet.csproj

DotNetTest

C# API测试

test\scr037\DotNetTest.csproj

ex_access

B树存取实例

examples_csharp\ex_access\ex_access.csproj

ex_btrec

使用记录号的b树的实例

examples_csharp\ex_btrec\ex_btrec.csproj

ex_env

环境操作实例

examples_csharp\ex_env\ex_env.csproj

ex_repquote

简单的集群实例

examples_csharp\ex_repquote\ex_repquote.csproj

ex_sequence

序列操作实例

examples_csharp\ex_sequence\ex_sequence.csproj

ex_txn

多线程事务实例

examples_csharp\ex_txn\ex_txn.csproj

上述工程可以在单个工程中编译,亦可在整个BDB C# API的解决方案中编译。

(1) 编译解决方案

BDB C# API解决方案已配置好所有BDB C#动态库所需的库及环境。因此,在配置管理器中选择平台(win32或者x64)和编译模式(debug或者release)后,编译该解决方案,便可生成相应的BDB C动态库,C#动态库以及所有实例的可执行文件。如图2和图3所示,进入配置管理器,选择编译配置、平台及工程项。

图片2

图片3

(2) 编译单个工程

单独编译表格1中的任一工程,打开其工程文件,编译前,应先编译其依赖项。上述10个工程的工程依赖关系,产生的主要对象及其路径如表格2所示:

工程名

工程依赖

产生对象

Db

build_windows\AnyCPU\{debug, release} \{libdb48.dll, libdb48d.dll}

build_windows\ AnyCPU {debug, release } \{libdb48.lib, libdb48d.lib}

db_csharp

db

build_windows\AnyCPU\{debug, release} \{ libdb_csharp48.dll, libdb_csharp48d.dll }

build_windows\AnyCPU\{debug, release } \{ libdb_csharp48.lib, libdb_csharp48d.lib }

db_dotnet

db, db_csharp

build_windows\AnyCPU\{debug, release } \ libdb_dotnet48.dll

DotNetTest

db, db_csharp, db_dotnet

test\scr037\bin\{debug, release}\DotNetTest.dll

ex_access

db, db_csharp, db_dotnet

build_windows\AnyCPU\{debug, release} \ex_access.exe

ex_btrec

db, db_csharp, db_dotnet

build_windows\AnyCPU\{debug, release} \ex_btrec.exe

ex_env

db, db_csharp, db_dotnet

build_windows\AnyCPU\{debug, release} \ex_env.exe

ex_repquote

db, db_csharp, db_dotnet

build_windows\AnyCPU\{debug, release}\ex_repquote.exe

ex_sequence

db, db_csharp, db_dotnet

build_windows\AnyCPU\{debug, release} \ex_sequence.exe

ex_txn

db, db_csharp, db_dotnet

build_windows\AnyCPU\{debug, release} \ex_txn.exe

3. 运行C# API的单元测试

C# API单元测试基于NUnit框架。NUnit是一个开源的面向所有.Net语言的单元测试框架,提供可视化界面和命令行的支持,可在http://www.nunit.org/index.php下载最新版本。

安装完NUnit后,编译DotNetTest测试工程,在<db-4.8.24>\test\scr037\bin\Debug\得到DotNetTest.dll。在NUnit中运行该测试类库前,需要确定libdb48.dlllibdb_csharp48.dlllibdb_dotnet48.dll都在环境变量或者当前目录下。在NUnit中打开生成的DotNetTest.dll,运行该工程,可得到测试结果。

4. 运行示例程序

BDB C# API解决方案提供了6个实例,它们分别是ex_accessex_btrecex_envex_repquoteex_sequenceex_txn。在解决方案中编译和运行实例工程,在Visual Studio设置该实例工程为启动工程,若依赖的动态链接库已编译,则编译和运行该实例即可。例如,运行ex_txn,编译C#库得到libdb48.dlllibdb_csharp48.dlllibdb_dotnet48.dll,打开ex_txn工程文件,如图4,编译该工程,运行结果如图5所示。

图片4

图片5

5. 基于BDB C# API的开发

使用BDB C# API进行基于数据库应用程序的开发,需要libdb48.dlllibdb_csharp48.dlllibdb_dotnet48.dll三个动态链接库。首先,在开发的工程中添加libdb_dotnet48.dll的引用,由于libdb_dotnet48.dll需要调用本地代码得到的libdb48d.dlllibdb_csharp48.dll。因此,libdb48d.dlllibdb_csharp48d.dll应放在本工程路径或者环境变量中,以便运行时加载。开发过程中,在代码中添加BDB C# API的命名空间,即“using BerkeleyDB”,便可使用BDB C# API。本文在此举一例子,打开数据库并插入一条Hello World的记录。代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using BerkeleyDB;

class Program {
      public static void Main(string[] args) {
             BTreeDatabaseConfig btreeDBConfig = new BTreeDatabaseConfig();
             btreeDBConfig.Creation = CreatePolicy.ALWAYS;
             btreeDBConfig.PageSize = 512;
             using (BTreeDatabase btreeDB = BTreeDatabase.Open(
                 "bdb.db", btreeDBConfig)) {

                    btreeDB.Put(new DatabaseEntry(BitConverter.GetBytes((int)1)),
                                     new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("Hello World!")));
                    KeyValuePair pair = btreeDB.Get(new DatabaseEntry(BitConverter.GetBytes((int)1)));
                    System.Console.WriteLine(ASCIIEncoding.ASCII.GetString(pair.Value.Data));
             }
      }
}

运行结果显示如下:

图片6

BDB是成熟高效的嵌入式引擎,个人认为它提供的C# API在小到手机等消费终端,大至企业级应用都可以使用上BDB这个成熟高效的数据库引擎。更多的信息请参考

http://www.oracle.com/technology/documentation/berkeley-db/db/programmer_reference/csharp.html,欢迎垂询。

  1. 寒星
    2009年10月14日21:09 | #1

    期待更多关于BDB C#方面的文章

  2. smallcat
    2009年10月15日10:20 | #2

    Hi 您好:
    在使用上述BerkeleyDb的C# Binding时发现个性能问题,当我使用HashDB时插入40W数据,Key为从0到40W,Value为1.5K 的随机字符串,未使用任何参数,数据库大小为1.1G,每次随机读取100条数据,发现读取时间大约为1200毫秒左右,请问速度是否正常,若不常常如何优化?谢谢。

  3. smallcat
    2009年10月15日10:36 | #3

    如果改为

    smallcat :
    Hi 您好:
    在使用上述BerkeleyDb的C# Binding时发现个性能问题,当我使用HashDB时插入40W数据,Key为从0到40W,Value为1.5K 的随机字符串,未使用任何参数,数据库大小为1.1G,每次随机读取100条数据,发现读取时间大约为1200毫秒左右,请问速度是否正常,若不常常如何优化?谢谢。

    如果改为BTreeDatabase 速度大概是800毫秒左右,硬件配置是普通硬盘+2G内存+3.0双核CPU。谢谢。

  4. Emily Fu
    2009年10月15日12:17 | #4

    你好,欢迎关注BDB C# API。从C# API的接口使用来说,请问key和value分别采用何种方式序列化?每次如何随机读取?是否使用了合适的比较方法读取数据?
    从数据库性能调优来说,建议在HashDatabaseConfig中调整pagesize和cachesize,具体可参考http://www.oracle.com/technology/documentation/berkeley-db/db/csharp/html/AllMembers_T_BerkeleyDB_HashDatabaseConfig.htm。

  5. smallcat
    2009年10月15日12:52 | #5

    感谢您的建议,您给我的文档我正在看,多谢。关于序列化是这样子的:
    i:为int32值
    s:为String类型
    DatabaseEntry key = new DatabaseEntry(BitConverter.GetBytes(i));
    DatabaseEntry val = new DatabaseEntry(Encoding.UTF8.GetBytes(s));
    但是在查询时只序列化了Key作为查询条件,查询结果并未反序列化,代码如下:
    Random ran = new Random(Environment.TickCount);
    for (int i = 0; i < 100; i++)
    {
    int k = ran.Next(400000);
    DatabaseEntry key = new DatabaseEntry(BitConverter.GetBytes(k));
    KeyValuePair pair = db.Get(key);
    }

  6. smallcat
    2009年10月15日12:53 | #6

    感谢您的建议,您给我的文档我正在看,多谢。关于序列化是这样子的:
    i:为int32值
    s:为String类型
    DatabaseEntry key = new DatabaseEntry(BitConverter.GetBytes(i));
    DatabaseEntry val = new DatabaseEntry(Encoding.UTF8.GetBytes(s));
    但是在查询时只序列化了Key作为查询条件,查询结果并未反序列化,代码如下:
    Random ran = new Random(Environment.TickCount);
    for (int i = 0; i < 100; i++)
    {
    int k = ran.Next(400000);
    DatabaseEntry key = new DatabaseEntry(BitConverter.GetBytes(k));
    KeyValuePair pair = db.Get(key);
    }
    以上,再次感谢。

  7. smallcat
    2009年10月15日13:44 | #7

    您好,刚刚按照您说的又做了个测试,把cachesize设为128M,pagesize设为8K,读刚刚没有优化参数创建的库文件速度很慢仍然在1秒钟左右,但是用这两个参数创建了一样的数据库后再读速度相当快,基本上都在16毫秒以下,感谢您的建议,谢谢。不过为什么会发生这种情况,能否告知,谢谢。

  8. Emily Fu
    2009年10月16日10:03 | #8

    @smallcat

    读取已经存在的数据库,新设置中pagesize并不起作用,请参考文档http://www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/dbset_pagesize.html中“If the database already exists when DB->open() is called, the information specified to DB->set_pagesize() will be ignored.”

    希望对你有帮助!

  9. smallcat
    2009年10月16日17:04 | #9

    您的文档对我很有帮助,谢谢。
    已经确认是在插入数据时PageSize设置过小导致OverflowPage所致。所以我针对PageSize与OverflowPage做了个简单的实验:
    Key都是Int32类型因此长度均为4bytes
    以下是PageSize所能容纳的最大Value长度
    PageSize:1024 ValueSize:239
    PageSize:2048 ValueSize:495
    PageSize:4096 ValueSize:1004
    PageSize:8K ValueSize:2020左右
    因此好像PageSize所能容纳的数据长度大概是其1/4左右,剩余3/4都被BerkeleyDb所占用?查了些资料也没有详述其间关系。迷惑不解。

  10. davidzhao
    2009年10月21日12:30 | #10

    不是的,Berkeley DB在每页占用的只有几十个字节。Berkeley DB计算overflow 阀值的方法是:首先,确保每页放得下最小数目的key,默认是2,不可能小于2的了.然后,它假设你的key和data都会很大,所以,都可能overflow,所以这个阀值比较小。

  11. 2009年10月28日09:55 | #11

    你好
    ex_txn 多线程事务实例 examples_csharp\ex_txn\ex_txn.csproj

    在这个例子中利用多线程 把PayloadData 以序列化的形式添加进去了

    取出来的时候 怎么取出 PayloadData 这个类的对象 利用Get方法

    KeyValuePair pair = db.Get(new BerkeleyDB.DatabaseEntry(ASCIIEncoding.ASCII.GetBytes(Key)), txn);

    BinaryFormatter formatter = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    ms.Position = 0;
    ms.SetLength(pair.Value.Data.Length);

    PayloadData put = (PayloadData)formatter.Deserialize(ms);

    这样不行 报错 怎么回事呀

  12. 2009年10月28日10:18 | #12

    已解决了

  13. 2009年10月28日16:00 | #13

    在put的时候 怎么设置 可以添加重复的key和data

    现在我添加重复key 可以 但是 key和data都重复 就报错了 难道不支持吗?

    我想实现 添加重复key 和data 覆盖原先来值 怎么实现呀

  14. Emily Fu
    2009年11月2日14:09 | #14

    若数据库有重复记录,应设置其为可重复的,例如在btree打开前,设置其BTreeDatabaseConfig中Duplicates为UNSORTED或者SORTED,可参考http://www.oracle.com/technology/documentation/berkeley-db/db/csharp/html/F_BerkeleyDB_BTreeDatabaseConfig_Duplicates.htm。

    若需要在put的时候限制插入记录的重复性,可使用BTreeDatabase.Put(), BTreeDatabase.PutNoDuplicate(), BTreeDatabase.PutNoOverwrite()达到不同的要求,可参考http://www.oracle.com/technology/documentation/berkeley-db/db/csharp/html/Methods_T_BerkeleyDB_BTreeDatabase.htm。

  15. 2009年11月3日18:01 | #15

    多谢

    请问下 我机器32位 程序写好都正常 布置到服务器上报错
    The type initializer for ‘BerkeleyDB.Internal.libdb_csharpPINVOKE’ threw an exception
    怎么回事呀 环境变量已经配置了 服务器是64位 我按照图2和图3所示 进行编译成64位 放到服务器上的

  16. 2009年11月4日14:05 | #16

    我按照图2和图3所示 设置成64位 进行编译 项目跳过 什么原因?

  17. Emily Fu
    2009年11月4日18:20 | #17

    @zhu
    请问你提到的异常在什么情况下抛出的?

  18. Emily Fu
    2009年11月4日18:24 | #18

    @zhu

    按照图2和图3设置成64位后,请检查configuration manager中的build一栏,是否所有需要的项目都选定被编译。在编译时,应右键solution中的rebuild all进行重编译。

  19. 2009年11月4日18:34 | #19

    你好
    我生成一个数组 每个数组里面有6个字段 每个字段的只要2个字母的一个值
    生成一百万的数据 数据库文件大小有500M 有什么方式可以设置文件大小的
    我设置 PageSize 的大小 好像作用不大 PageSize的值越小 文件反而越大

  20. 2009年11月4日18:48 | #20

    char[] tempc = new char[] { ‘a’, ‘b’, ‘c’, ‘d’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’ }

    BinaryFormatter formatter = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    formatter.Serialize(ms, o);
    Byte[] bytes = ms.GetBuffer();
    dbt.Data = bytes;
    存10W条 大小还是50M

  21. Emily Fu
    2009年11月5日10:20 | #21

    @乌鸦精

    你好,在已有的BDB方法中,文件大小均会根据运行时bdb的操作(例如insert, delete, compact等等)改变,即目前没有方法设置文件大小。

    设置pagesize不能直接设置文件大小。一个数据库包括很多页,每一页除了存储一定数量的数据外,还有一些头结构。设置较小的pagesize,数据的有效空间则相对较小,需要的页较多,数据库文件大小不会减小。具体如何设置合适的pagesize可以参考http://www.oracle.com/technology/documentation/berkeley-db/db/programmer_reference/general_am_conf.html#am_conf_pagesize。

    影响文件大小的因素有很多。如上段提到的pagesize。如不同的access method页面及记录的插入方式不同,从而占用的空间不同。具体如何选择合适的access method可以参考http://www.oracle.com/technology/documentation/berkeley-db/db/programmer_reference/am_conf_select.html。又如compact操作可以对数据库进行压缩,适当地减小数据库文件,具体可以参考http://www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/dbcompact.html。

    总之,合理地选择access method,设置符合你应用程序特点的pagesize,以及正确的使用API。

  22. 2009年11月5日13:58 | #22

    ex_txn 多线程事务实例 在这个例子中 inMem 这个变量设置成true 第一次运行没问题 当第一次运行完 这个数据库文件已有数据 在启动运行 db = BTreeDatabase.Open(dbName, dbCfg); 这个时候打开数据库 就报错了 郁闷 照理说 应该加载上次添加过数据的 文件
    为什么打不开呢 例子我其他地方都没动 就运行 把inMem设置true 报错 设置false 没事

  23. 2009年11月5日14:03 | #23

    另外我看 4.8版本支持批量插入和批量删除
    C# API 里面 我怎么没找到呢 有这方面的例子吗?
    还有 database间外键的约束 我看过以前版本的例子 C# 4.8 API里面我也没找到关于这方面的东西 跪求例子 多谢

  24. chaohuang
    2009年11月5日14:15 | #24

    @zhu
    你方便告知你在什么应用中用到BDB 4.8 C#吗?我给你发过Email,没有得到你的答复…

  25. 2009年11月5日15:13 | #25

    @chaohuang
    给你回复了 mail 查收下 多谢

  26. ..
    2009年11月5日17:28 | #26

    ..

  27. Leasing
    2009年11月6日22:41 | #27

    @Emily Fu
    5. 批量插入和批量删除
    众所周知,通过BDB API读取记录时,可以每次读一条也可以批量读取。在4.8里, 我们又提供了批量插入和删除的功能,从而来提高效率。批量查询可以通过设置DB_MULTIPLE or DB_MULTIPLE_KEY in DBC->get 来实现;而在DB->put() & DB->del() 中加上 DB_MULTIPLE 和 DB_MULTIPLE_KEY 标志来实现批量插入和删除。具体性能提升指 标取决于应用场景和平台。

    我仔细看过c# API Database 批量插入和批量删除 不支持?

  28. Leasing
    2009年11月7日00:06 | #28

    @Emily Fu
    // public byte[][] Data;
    /* No Public Constructor */
    //internal MultipleDatabaseEntry(DatabaseEntry dbt) {
    // byte[] dat = dbt.UserData;
    // List tmp = new List();
    // uint pos = dbt.ulen – 4;
    // int off = BitConverter.ToInt32(dat, (int)pos);
    // for (int i = 0; off > 0; off = BitConverter.ToInt32(dat, (int)pos), i++) {
    // pos -= 4;
    // int sz = BitConverter.ToInt32(dat, (int)pos);
    // tmp.Add(new byte[sz]);
    // Array.Copy(dat, off, tmp[i], 0, sz);
    // pos -= 4;
    // }
    // Data = tmp.ToArray();
    //}

    难道这就是要实现 批量的代码?

  29. Leasing
    2009年11月7日00:16 | #29

    有了这段代码 既然你们不实现那我就给实现了把

  30. Emily Fu
    2009年11月13日10:03 | #30

    @zhu
    日志用于恢复数据库,维护数据的持久性。设置日志为内存存储方式(inmem = true),日志不会存储在磁盘上,数据库不保持其持久性。因此,在你的场景中, 第二次运行时,该环境不能再次被使用。具体可参考文档http: //www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/envlog_set_config.html 中DB_LOG_IN_MEMORY的说明。

    若仍需要内存日志数据库中的数据文件,请在关闭环境前调用DB_ENV->lsn_reset (),则数据文件仍可使用,具体可参考文档http: //www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/envlsn_reset.html。

  31. 2009年11月13日16:48 | #31

    @Leasing
    批量查询弄出来了?

    @Emily Fu
    多谢!
    4.8 C# API中 简单的集群实例 我做了测试 两天机器同步 性能还算可以插入数据在20毫秒左右 取数据也很快 几乎不用时间

    但是 我用三台机器测试 性能就慢下来了 插入数据 需要2000毫秒左右 取数据性能不变 还行

    是否里面有参数设置问题? 还是正常?

  32. 2009年11月16日15:01 | #32

    @Emily Fu
    ex_repquote 简单的集群实例 在这个例子中 我启动一个主机 两个客户端 任意重新启动一个客户端 重新启动这个客户端的数据 怎么就没了?可不可以保存下来呢?
    如果我数据有几十个G,甚至更多 运行期间一个客户机维护停止,在启动起来 需要从零去同步数据,这样不行吧?

  33. 2009年11月28日15:01 | #33

    你好
    如果我设置了可以写入重复值 那读取的时候怎么操作

  34. 2009年11月28日15:37 | #34

    希望能给一个写入与读取 重复记录的例子 简单点都可以
    我的 mail 是xuyong619@21cn.com

  35. 2009年12月1日17:02 | #35

    你好 重复读取写入弄明白 现在又遇到一个问题 我在写入数据的时候大概是120W 文件大小是1G 如果是在一个循环体里写入 大概写到50W的 500多M的时候写入就很慢了 如果我换个方式写入 每次都只写入8W左右 已追加的方式写入到一个文件里 速度就很快 每次速度很平均 请问这是怎么回事 我该如何调整

  36. Emily Fu
    2009年12月2日18:00 | #36

    @乌鸦精

    你好,如果数据库允许重复值或者有序重复值,可以使用DB句柄或者DBcursor句柄读取这些重复值。具体根据你的需求,使用其相应的flags。请参考http://www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/dbget.html的DB->get()和http://www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/dbcget.html的DBcursor->get()。

    如果你在使用C# API,请根据你使用何种数据库(BTreeDatabase, HashDatabase, QueueDatabase, RecnoDatabase),选择其相应的成员函数。

  37. 2009年12月14日19:23 | #37

    你好:
    我这样操作获得多条记录 (数据集比较大)为什么全部操作完了内存不释放
    mBtreeDB.GetMultiple(keyT, 10240)

    mBtreeDB.Close();
    mBtreeDB.Dispose();
    mBtreeDB = null;
    mBtreeConfig = null;
    GC.Collect();

    也都释放不了 他占据的(十多G)内存

    其他的查询唯一 和游标都没此问题
    请问是怎么回事
    我现在处理几千万数据效率还是不错的 比之前使用SQL2005要快不少

  38. 2009年12月14日19:29 | #38

    注明下
    我是开启的线程完成的
    在任务管理器里面也都看不到那占用的内存
    除了关闭程序 可以释放完 没有其他的办法

  39. Emily Fu
    2009年12月18日14:18 | #39

    @乌鸦精
    你好,请问除了GetMultiple以外,你的进程还进行了什么操作?

  40. 2009年12月19日10:08 | #40

    请问c# Berkeley DB API 什么时候能支持批量插入

  41. 2009年12月21日11:09 | #41

    我在一个线程里有 一个 Cursor 另外还开启了3个查询(两个查询唯一的 一个查询多行的)还有就是写入lucene 因为我的数据量比较大 打开一个连接就没关闭 到最后数据操作完了 才选择关闭
    最多可以开启16个线程
    还有一个比较严重的问题是 会造成内存写入错误导致服务器重启
    重启也不是每次发生 有时候会有时候不会 我做了很多测试 觉得问题有可能就出在 mBtreeDB.GetMultiple(keyT, 10240) 其实我每次查询的数据操作完成以后 根本不需要放在内存里 不会重复使用的 怎么才能做到使用完了就释放掉内存里的数据
    我现在做了个操作就是读取了10W条数据后 关闭数据库重新打开连接(其实是没有效果的) 就算所有操作都完成了关闭所有连接都不会释放内存 我只能在程序里做到所有操作完成后 程序自动关闭 然后另外写一个监控程序 判断进程里的这个程序不存在 再开启 如果不导致服务器意外重启 这个项目基本上可以应用了 比以前操作SQLSERVER效率上提高了百分之80以上
    服务器的是64位的 重启的时候物理内存还有10G左右 BDB大概占了10G CPU是16核的 使用了大概百分之40
    还有就是在数据写入的时候会造成数据文件损坏 有什么补救的方式吗

    如果可能 我把代码发给你
    谢谢了

  42. 2009年12月21日11:12 | #42

    CPU使用百分之40是开启16个线程 最高峰的时候 一般是20到30左右

  43. Emily Fu
    2009年12月22日15:52 | #43

    你好,我们会做进一步的测试,确定你所描述的场景。

    谢谢!

  44. jenvin
    2009年12月27日11:10 | #44

    您好,我在使用JoinCursor 的时候,调用Move,或MoveNextItem 会抛出异常
    page 0: illegal page type or format
    PANIC: Invalid argument
    不知道为什么,示例完全是参照 测试代码中的JoinCursorTest.TestMoveJoinCursor,没有做任何改动。使用SecondaryCursor没问题,能行告诉我为什么吗?

    //这里抛出异常,不能遍历
    foreach (KeyValuePair pair in joinCursor)
    {
    /*
    * Confirm that the key got by join cursor has 0 at
    * its highest byte and 1 at its lowest byte.
    */
    Assert.AreEqual(0, pair.Key.Data[pair.Key.Data.Length - 1]);
    Assert.AreEqual(1, pair.Key.Data[0]);
    }

  45. Emily Fu
    2009年12月29日14:14 | #45

    能否提供更多的使用场景和代码以便分析。

  46. luoyong
    2010年1月13日17:20 | #46

    强烈建议 :提供更多的代码使用例子

  47. 123456
    2010年1月14日11:41 | #47

    我的邮箱是:weis@yahoo.cn
    有些问题想咨询您?期待回音!

  48. 123456
    2010年1月14日11:42 | #48

    我的邮箱是:weis2007@yahoo.cn
    有些问题想咨询您?期待回音!

  49. 123456
    2010年1月15日15:07 | #49

    问题:Berkeley DB中有很多条数据,其中KEY为“001”的有三条,它们分别对应不同的VALUE值;请问怎么能从数据库中只读取KEY为001的数据,如果用游标的话,应该怎么读?谢谢!

  50. kela
    2010年1月25日12:18 | #50

    @zhu
    在x64上编译了吗?后来如何解决的?能不能共享一下。
    我手头没有x64的环境啊。
    官方如果直接有下载就好了…

评论分页
1 2 653
本文的评论功能被关闭了.
Դ