伯克利数据库,多线程致命错误

Berkeley DB, Multithreaded FATAL ERROR

本文关键字:致命错误 多线程 数据库 伯克利      更新时间:2023-10-16

我写了一个程序,在C/c++中像混合一样使用Berkeley DB。我有一个叫做bdb的类,它有这个方法。

    int open(char *db_name)
 {
  flags = DB_CREATE;
  u_int32_t envCreateFlags = DB_CREATE |
                           DB_INIT_LOCK|
                           DB_INIT_LOG|
                           DB_INIT_MPOOL|
                           DB_INIT_TXN|
                           DB_RECOVER |
                           DB_THREAD;

  ret = db_env_create(&dbenv, 0);
        dbenv->err(dbenv,ret,"err db_env_create ");         
  ret = dbenv->open(dbenv,"./",envCreateFlags,0);
       dbenv->err(dbenv,ret,"err db_env_open ");     
  ret = db_create(&dbp,dbenv, 0);
dbp->err(dbp,ret,"err db_create ");     
  ret = dbp->open(dbp,        /* DB structure pointer */
                  NULL,       /* Transaction pointer */
                  db_name, /* 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) */
dbp->err(dbp,ret,"err dbp open  ");     

  return ret;
 };

那么接下来在程序中我将使用像

这样的方法
 int getEntry( char *url ,unsigned int *fp)
 {
  DBT key, data;
   DBC *cursorp;
   dbp->cursor(dbp, NULL, &cursorp, 0); 
   memset(&key, 0, sizeof(DBT));
   memset(&data, 0, sizeof(DBT));
   key.data = fp;
   key.ulen = sizeof(unsigned int);
   key.flags = DB_DBT_USERMEM;
   data.data = url;
   data.ulen = sizeof(char) * maxUrlSize;
   data.flags = DB_DBT_USERMEM;
   ret = cursorp->c_get(cursorp, &key,&data, DB_PREV);
  if (cursorp != NULL) 
   cursorp->close(cursorp); 

  if (ret == DB_NOTFOUND)
   return -1;
}

因此,对象被创建,然后地址被分配给多个线程。

结果是每次我在程序开始后得到

PANIC: fatal region error detected; run recovery
PANIC: fatal region error detected; run recovery

我得到一个分段错误的行

ret = cursorp->c_get(cursorp, &key,&data, DB_PREV);

我不知道为什么?

您可以考虑将您的问题发布到OTN上的Berkeley DB论坛。有一个由应用程序开发人员、支持工程师和BDB开发人员组成的活跃社区,他们在该论坛上进行互动。

这里有几个快速的可能性:

    你的应用程序是否可能在每个线程中调用dbenv->open() ?这会产生你所描述的症状。您只希望在应用程序开始时调用一次dbenv->open。
  • 你需要在打开数据库句柄时指定DB_THREAD。

下面的文档可能是有用的:《c++入门指南》第4章,《c++入门指南》中的示例,《参考指南》中的程序员注意事项章节。

如果这不能解决你的问题,我鼓励你发帖到上面列出的伯克利数据库论坛。