Skip to Main Content

Berkeley DB Family

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Why my application crashed using Berkeley DB C++ API?

551054Dec 11 2006 — edited Dec 11 2006
Hi,

I am new to Berkeley DB. I want to use a queue database in my application. In my application,there are one thread for appending record to database and many threads read record from database,and each reading thread delete the head record after it is read from the database.
The application will crash when the DB::put() is called( in RealTimeDB::PutRecord()) or when the DB::get() is called(in RealTimeDB::GetRecord). In case reading record from database ,If use cursor -> get() , it will work. But each time DB::put() is called, the application will crash.
The DbEnv and Db is opened in primary thread, and the database will be accessed in other threads.
The RealTimeDB class is showed below:

#define KEYLEN sizeof(db_recno_t)
#define MSG_LEN 4096

RealTimeDB::RealTimeDB(char pHomeDir, char pDBFileName)
: pdb_(NULL), // Instantiate Db object
dbenv_(NULL), //Database environment
putrecno_(0),
getrecno_(0)

{
pDBHomeDir_ = pHomeDir; // Database Homw directory
pDBFileName_ = pDBFileName; // Database file name
}

// Private member used to close a database. Called from the class
// destructor.
void RealTimeDB::close()
{
// Close the db
if (NULL != pdb_)
{
pdb_->close(0);
}
std::cout << "Database " << pDBFileName_
<< " is closed." << std::endl;

if (NULL != dbenv_)
{
(void)dbenv_->close(0);
}

delete pdb_;
delete dbenv_;
}

int RealTimeDB::CreateDB()
{
u_int32_t envFlags;
u_int32_t dbFlags;

envFlags =
DB_CREATE | // Create the environment if it does not exist
DB_INIT_LOCK | // Initialize the locking subsystem
DB_INIT_MPOOL | // Initialize the memory pool (in-memory cache)
DB_INIT_TXN |
DB_THREAD; // Cause the environment to be free-threaded

// Create and open the environment


dbenv_ = new DbEnv(0);
if (NULL == dbenv_)
{
return (-1);
}

.
dbenv_->set_lk_detect(DB_LOCK_MINWRITE);

dbenv_->open(pDBHomeDir_, envFlags, 0);

pdb_ = new Db(dbenv_, 0);
if (NULL == pdb_)
{
return (-1);
}

pdb_->set_pagesize(4 * MSG_LEN);

pdb_->set_q_extentsize(1024);

// pdb_->set_flags(DB_INORDER);

// Open the database
dbFlags = DB_CREATE | // Allow database creation
DB_THREAD | // Free-threaded
DB_AUTO_COMMIT; // Allow autocommit


pdb_->open( NULL, // Txn pointer
pDBFileName_, // File name
NULL, // Logical db name
DB_QUEUE, // Database type (using btree)
dbFlags, // Open flags
0 ); // File mode. Using defaults

return (0);

}

int RealTimeDB::PutRecord(char *pbuf, int bufsize)
{
int iRet = 0;
DbTxn *txn = NULL;

if (NULL == pbuf || bufsize <= 0)
{
return (-1);
}

Dbt key((void *)&putrecno_, KEYLEN);
Dbt data((void *)pbuf, MSG_LEN);

iRet = pdb_->put(NULL, &key, &data, DB_APPEND);

if (0 != iRet)
{
return iRet;
}

return 0;
}

int RealTimeDB::GetRecord(char *pbuf, int bufsize)
{
int iRet = 0;
/* Dbc *cursorp = NULL;

pdb_->cursor(NULL, &cursorp, 0);

Dbt key;
Dbt data((void *)&pbuf, MSG_LEN);

if (cursorp->get(&key, &data, DB_NEXT) == 0)
{
cursorp->del(0);
cursorp->close();
return 0;
}
else
{
cursorp->close();
return DB_KEYEMPTY;
}
*/


db_recno_t recordno(getrecno_);
int iErrno = 0;

if (NULL == pbuf || bufsize <= 0)
{
return (-1);
}

Dbt key((void *)&recordno, KEYLEN);
Dbt data((void *)&pbuf, MSG_LEN);
data.set_flags(DB_DBT_USERMEM);

iRet = pdb_->get(NULL, &key, &data, DB_CONSUME);

return 0;
}

Wu Su
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jan 8 2007
Added on Dec 11 2006
4 comments
1,194 views