I have an environment with DB_LOG_IN_MEMORY flag. After filling the DB_HASH (or DB_BTREE) database with some key/value pairs I do checkpoint and explicitly close all opened handles. When I attach to environment and open database second time I catch the exception from Db::put method. Here is a small example program built with Berkeley DB 6.1.19
#include "../db_cxx.h"
void foo()
{
DbEnv env( 0 );
env.set_lg_bsize( 10 * 1024 * 1024 );
env.set_flags( DB_TXN_NOSYNC, 1 );
env.log_set_config( DB_LOG_IN_MEMORY, 1 );
env.open( "d:\\test", DB_CREATE | DB_INIT_LOG | DB_INIT_TXN | DB_INIT_MPOOL | DB_RECOVER | DB_PRIVATE, 0 );
Db db( &env, 0 );
db.open( nullptr, "test.bdb", nullptr, DB_HASH, DB_AUTO_COMMIT | DB_CREATE, 0 );
DbTxn *txn;
env.txn_begin( nullptr, &txn, 0 );
for( int i = 0; i < 1000; ++i )
{
Dbt k;
k.set_data( &i );
k.set_ulen( sizeof( i ) );
k.set_flags( DB_DBT_USERMEM );
Dbt v;
v.set_data( &i );
v.set_ulen( sizeof( i ) );
v.set_flags( DB_DBT_USERMEM );
db.put( txn, &k, &v, 0 );
}
txn->commit( 0 );
env.txn_checkpoint( 0, 0, DB_FORCE );
db.close( 0 );
env.close( 0 );
}
int main( int argc, char* argv[] )
{
try
{
std::cout << "Attempt #1" << std::endl;
foo();
std::cout << "Attempt #2" << std::endl;
foo();
}
catch( DbException const& e )
{
std::cerr << "DbException: " << e.what() << std::endl;
}
return 0;
}
Output:
Attempt #1
Attempt #2
BDB2506 file test.bdb has LSN 1/84854, past end of log at 1/165
BDB2507 Commonly caused by moving a database from one database environment
BDB2508 to another without clearing the database LSNs, or by removing all of
BDB2509 the log files from a database environment
BDB4511 Error: closing the transaction region with active transactions
DbException: Db::put: Invalid argument
What am I doing wrong? That works fine If I don't turn on DB_LOG_IN_MEMORY flag.