2016-09-20 33 views
0

我正在编写一组必须在公共数据库上运行的程序,可能同时发生。为了简单起见(对于用户),我不想要求安装数据库服务器。因此,我安装了Berkeley DB,在那里可以启动一个程序并让它创建数据库(如果它不存在)。使用Berkeley DB事务处理的问题

为了让程序在数据库上同时工作,必须使用5.x版本中存在的事务功能(这里我使用python3-bsddb3 6.1.0-1 + b2和libdb5.3 5.3.28 -12):文件清楚地表明它可以完成。不过,我赶紧跑了麻烦,即使有一些基本的任务:

  • 计划1表
  • 方案2有扫描之前由程序加1的记录,用另外的数据更新它们初始化记录。

为了加快速度,有一个索引额外的数据。当程序1创建记录时,附加数据不存在,因此指向该记录的指针将被添加到索引下的空键上。然后,计划2可以快速寻找尚未更新的记录。

即使不同时运行,记录更新程序在几次更新后崩溃。首先它抱怨互斥区域空间不足。我必须用一个模糊的DB_CONFIG文件解决这个问题,然后运行db_recover。

接下来,在几次更新后再次发出抱怨'无法分配内存 - BDB3017无法从缓冲区缓存中分配空间'。 db_recover和重新启动这个程序的确有窍门,只能让它再次崩溃,之后几条记录会出现同样的错误。我甚至没有提及并发使用:当其中一个程序在另一个正在运行时启动时,它们几乎立即崩溃,死锁,关于损坏的段恐慌并要求运行恢复。我做了很多改变,所以我经历了各种各样的错误,这些错误在搜索时经常产生不相关的匹配。我甚至重写了db调用来使用lmdb,实际上它工作得很好,而且非常快,这往往表明我的程序逻辑没有错。不幸的是,似乎lmdb生成的数据文件非常稀少,并且迅速增长到不可接受的大小。

从我所说的看来,也许有些资源正在泄漏某处。我很犹豫是否直接在C中重写所有这些以检查问题是否可以来自Python绑定。

我可以和我一起更新代码的问题,但是现在ti已经够长了。我正在寻找那些在BDB中使用过交易性资料的人,用于类似的用途,这可能会将我指向一些陷阱。

感谢

回答

0

RPM(见http://rpm5.org)使用Berkeley DB的交易模式。有相当多的陷阱,取决于你正在尝试的。

您已经找到DB_CONFIG:您必须配置互斥锁和锁的大小,默认值总是太小。

在开发过程中需要运行db_recover也很痛苦。最好的修复(imho)是在打开时自动执行恢复,方法是检查DB_RUNRECOVERY的返回码,然后用DB_RECOVER重新打开dbenv。

死锁通常是设计/编码错误:运行db_stat -CA查看什么是死锁(或持有哪些锁)并调整程序。 “与lmdv协同工作”并不足以声明工作代码;-)

通过valgrind和/或BDB编译使用-fsanitize:address可以看到泄漏。请注意,除非您使用覆盖和/或编译BDB进行初始化,否则valgrind将报告错误的未初始化。