Berkeley DB 无法在不关闭数据库的情况下访问数据

Posted

技术标签:

【中文标题】Berkeley DB 无法在不关闭数据库的情况下访问数据【英文标题】:Berkeley DB can't put then access data without closing db 【发布时间】:2016-09-04 00:30:44 【问题描述】:

我正在尝试使用 berkeley DB 来存储和获取简单的密钥/数据对,但这并不符合我的预期。 我创建了一个函数 ( putdb() ) 将密钥/数据对放入数据库,另一个函数 ( getdb() ) 检索该对。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
DB *dbp;
void opendb(void)

        int ret; 
        if ((ret = db_create(&dbp, NULL, 0)) != 0)
                exit(EXIT_FAILURE);
        if ((ret = dbp->open(dbp, NULL, "db.db", NULL,DB_BTREE, DB_CREATE, 0664)) != 0)
                exit(EXIT_FAILURE);



void putdb(const char *key, const char *value)

    DBT keyValue, dataValue;
    memset(&keyValue, 0, sizeof(keyValue));
    memset(&dataValue, 0, sizeof(dataValue));

    keyValue.size = sizeof(key);
    dataValue.size = sizeof(value);

    keyValue.data = malloc(keyValue.size);
    strcpy(keyValue.data,key);

    dataValue.data = malloc(dataValue.size);
    strcpy(dataValue.data,value);

    if ((ret = dbp->put(dbp, NULL, &keyValue, &dataValue, 0)) == 0)
            printf("db: %s: key stored.\n", (char *)keyValue.data);
    else 
            dbp->err(dbp, ret, "DB->put");
    
    dbp->sync(dbp, 0);


void getdb(const char *key,const char *value)

    DBT keyValue, dataValue;
    memset(&keyValue, 0, sizeof(keyValue));
    memset(&dataValue, 0, sizeof(dataValue));

    keyValue.size = sizeof(key);
    dataValue.size = sizeof(value);

    keyValue.data = malloc(keyValue.size);
    strcpy(keyValue.data,key);

    dataValue.data = malloc(dataValue.size);
    strcpy(dataValue.data,value);

    if ((ret = dbp->get(dbp, NULL, &keyValue, &dataValue, 0)) == 0)
            printf("db: %s: key retrieved: data was %s.\n",
                (char *)keyValue.data, (char *)dataValue.data);
    else 
            dbp->err(dbp, ret, "DB->get");
    

void closedb(void)

    dbp->close(dbp, 0);
    //TODO : error code return check

和主文件:

int main()

    opendb();
    putdb("toto","titi");
    getdb("toto","titi");
    closedb();
 

我得到:

db: toto: key stored.
DB->get: BDB0073 DB_NOTFOUND: No matching key/data pair found

你能解释一下为什么吗?

如果我改变了我的主要功能,请注意:

int main()

    opendb();
    putdb("toto","titi");
    closedb();
    opendb();
    getdb("toto","titi");
    closedb();

然后就可以了! :

db: toto: key stored.
db: toto: key retrieved: data was titi.

【问题讨论】:

您添加 C++ 标签的任何原因? 如果您使用的是 32 位平台,那么您就是在分配之外进行编写,这就是未定义的行为。在 64 位架构上,您正在读取未初始化的内存,这也是 UB,并且很可能导致未找到密钥的错误。在所有情况下,您都在泄漏内存。你可能想解决这些问题,即使它不能解决直接的问题(尽管它可能)。 【参考方案1】:

您从教程中复制了太多内容。他们可以使用sizeof("a string"),但您必须在putdbgetdb 中都使用strlen(key)

keyValue.size = strlen(key);
dataValue.size = strlen(value);

【讨论】:

通常情况下,检索键时不会提供数据值。 getdb("key", "value") 建议 OP 不需要更多地了解数据存储。 :) @rici yepp,正如我所说的“你从教程中复制了太多”。是不是有点太微妙了? 我不知道你指的是什么教程,但是如果复制了malloc snd strcpy,这是一个非常糟糕的教程,应该尽早摆脱它的痛苦可能的机会。可悲的是,确实存在这样的反教程,但我怀疑这不是过度复制,而是过度阐述,也许是基于一些以前同化的货物崇拜。无论如何,最低限度的解毒剂可能是一个简单的可复制的例子。 @rici 我认为它来自官方教程,就像在这里找到的一样:web.stanford.edu/class/cs276a/projects/docs/berkeleydb/…(或更新的版本)。我不知道如何处理解毒剂,但我想我会试一试。 oO 我为自己的错误感到羞耻!!当然我不能在指针上使用 sizeof 。现在它起作用了。非常感谢。

以上是关于Berkeley DB 无法在不关闭数据库的情况下访问数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在不安装的情况下在应用程序中使用 Berkeley DB

应该在没有磁盘容器的情况下使用 Berkeley DB XML?

Berkeley DB 在没有交易的情况下损坏?

Berkeley DB 错误:无法锁定 je.lck 文件

Berkeley-DB:多个数据库上的原子事务

检查 Berkeley DB C++ API 中是不是存在密钥 [关闭]