Skip Menu |

This queue is for tickets about the BerkeleyDB CPAN distribution.

Report information
The Basics
Id: 50456
Status: resolved
Priority: 0/
Queue: BerkeleyDB

People
Owner: Nobody in particular
Requestors: mdorman [...] ironicdesign.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.39
Fixed in: (no value)



Subject: Several important environmental parameters unsettable
In trying to write a transactional BDB back-end for SpamAssassin's Bayes storage, I've run into the need to set several parameters that are only available after the DB_ENV is created, but before it is open()'ed. In the SA environment, requiring the user to create and/or maintain a DB_CONFIG file is sub-optimal. I recognize that willy-nilly adding more parameters to BerkeleyDB::Env's ->new() is probably sub-optimal, but short of significant surgery (to allow a flexible way to specify all post-create-pre-new parameters) that I didn't feel comfortable undertaking, adding the necessary parameters seemed the best route. I also "fixed" the existing set_tx_max and get_tx_max functions, insofar as I don't see how they could have ever worked, but set_tx_max is still an academic exercise since we have no way to invoke it at the right time, and it should likely be eliminated. Please note that this patch would also allow the resolution of RT#44907.
Subject: patch.diff
diff -uNr --exclude='debian*' BerkeleyDB-0.39/BerkeleyDB.pm libberkeleydb-perl-0.39/BerkeleyDB.pm --- BerkeleyDB-0.39/BerkeleyDB.pm 2009-06-03 18:50:39.000000000 -0400 +++ libberkeleydb-perl-0.39/BerkeleyDB.pm 2009-10-13 09:33:48.000000000 -0400 @@ -807,6 +807,11 @@ SetFlags => 0, Cachesize => 0, LockDetect => 0, + TxMax => 0, + LogConfig => 0, + MaxLockers => 0, + MaxLocks => 0, + MaxObjects => 0, Verbose => 0, Config => undef, Encrypt => undef, diff -uNr --exclude='debian*' BerkeleyDB-0.39/BerkeleyDB.pod.P libberkeleydb-perl-0.39/BerkeleyDB.pod.P --- BerkeleyDB-0.39/BerkeleyDB.pod.P 2009-06-02 18:23:20.000000000 -0400 +++ libberkeleydb-perl-0.39/BerkeleyDB.pod.P 2009-10-13 12:34:47.000000000 -0400 @@ -161,6 +161,11 @@ [ -Flags => number, ] [ -SetFlags => bitmask, ] [ -LockDetect => number, ] + [ -TxMax => number, ] + [ -LogConfig => number, ] + [ -MaxLockers => number, ] + [ -MaxLocks => number, ] + [ -MaxObjects => number, ] [ -SharedMemKey => number, ] [ -Verbose => boolean, ] [ -Encrypt => { Password => "string", @@ -218,6 +223,31 @@ If present, this parameter sets the size of the environments shared memory buffer pool. +=item -TxMax + +If present, this parameter sets the number of simultaneous +transactions that are allowed. Default 100. This default is +definitely too low for programs using the MVCC capabilities. + +=item -LogConfig + +If present, this parameter is used to configure log options. + +=item -MaxLockers + +If present, this parameter is used to configure the maximum number of +processes doing locking on the database. Default 1000. + +=item -MaxLocks + +If present, this parameter is used to configure the maximum number of +locks on the database. Default 1000. This is often lower than required. + +=item -MaxObjects + +If present, this parameter is used to configure the maximum number of +locked objects. Default 1000. This is often lower than required. + =item -SharedMemKey If present, this parameter sets the base segment ID for the shared memory diff -uNr --exclude='debian*' BerkeleyDB-0.39/BerkeleyDB.xs libberkeleydb-perl-0.39/BerkeleyDB.xs --- BerkeleyDB-0.39/BerkeleyDB.xs 2009-06-03 18:50:39.000000000 -0400 +++ libberkeleydb-perl-0.39/BerkeleyDB.xs 2009-10-13 09:33:26.000000000 -0400 @@ -2346,6 +2346,11 @@ int setflags = 0 ; int cachesize = 0 ; int lk_detect = 0 ; + int tx_max = 0 ; + int log_config = 0 ; + int max_lockers = 0 ; + int max_locks = 0 ; + int max_objects = 0 ; long shm_key = 0 ; char* data_dir = 0; char* log_dir = 0; @@ -2368,6 +2373,11 @@ SetValue_pv(server, "Server", char *) ; SetValue_iv(cachesize, "Cachesize") ; SetValue_iv(lk_detect, "LockDetect") ; + SetValue_iv(tx_max, "TxMax") ; + SetValue_iv(log_config,"LogConfig") ; + SetValue_iv(max_lockers,"MaxLockers") ; + SetValue_iv(max_locks, "MaxLocks") ; + SetValue_iv(max_objects,"MaxObjects") ; SetValue_iv(shm_key, "SharedMemKey") ; SetValue_iv(thread_count, "ThreadCount") ; SetValue_pv(data_dir, "DB_DATA_DIR", char*) ; @@ -2510,6 +2520,36 @@ Trace(("set_lk_detect [%d] returned %s\n", lk_detect, my_db_strerror(status))); } + + if (status == 0 && tx_max) { + status = env->set_tx_max(env, tx_max) ; + Trace(("set_tx_max [%d] returned %s\n", + tx_max, my_db_strerror(status))); + } + + if (status == 0 && log_config) { + status = env->log_set_config(env, log_config, 1) ; + Trace(("log_set_config [%d] returned %s\n", + log_config, my_db_strerror(status))); + } + + if (status == 0 && max_lockers) { + status = env->set_lk_max_lockers(env, max_lockers) ; + Trace(("set_lk_max_lockers [%d] returned %s\n", + max_lockers, my_db_strerror(status))); + } + + if (status == 0 && max_locks) { + status = env->set_lk_max_locks(env, max_locks) ; + Trace(("set_lk_max_locks [%d] returned %s\n", + max_locks, my_db_strerror(status))); + } + + if (status == 0 && max_objects) { + status = env->set_lk_max_objects(env, max_objects) ; + Trace(("set_lk_max_objects [%d] returned %s\n", + max_objects, my_db_strerror(status))); + } #ifdef AT_LEAST_DB_4_1 /* set encryption */ if (enc_passwd && status == 0) @@ -4932,35 +4972,36 @@ RETVAL int -set_tx_max(txn, max) - BerkeleyDB::Txn txn +set_tx_max(env, max) + BerkeleyDB::Env env u_int32_t max PREINIT: dMY_CXT; INIT: - ckActive_Transaction(txn->active) ; + ckActive_Database(env->active) ; CODE: #ifndef AT_LEAST_DB_2_3 softCrash("$env->set_tx_max needs Berkeley DB 2_3.x or better") ; #else - RETVAL = txn->Status = txn->txn->set_tx_max(txn->txn, max); + dieIfEnvOpened(env, "set_tx_max"); + RETVAL = env->Status = env->Env->set_tx_max(env->Env, max); #endif OUTPUT: RETVAL int -get_tx_max(txn, max) - BerkeleyDB::Txn txn +get_tx_max(env, max) + BerkeleyDB::Env env u_int32_t max = NO_INIT PREINIT: dMY_CXT; INIT: - ckActive_Transaction(txn->active) ; + ckActive_Database(env->active) ; CODE: #ifndef AT_LEAST_DB_2_3 softCrash("$env->get_tx_max needs Berkeley DB 2_3.x or better") ; #else - RETVAL = txn->Status = txn->txn->get_tx_max(txn->txn, &max); + RETVAL = env->Status = env->Env->get_tx_max(env->Env, &max); #endif OUTPUT: RETVAL @@ -5415,7 +5456,7 @@ (void)db_version(&Major, &Minor, &Patch) ; /* Check that the versions of db.h and libdb.a are the same */ if (Major != DB_VERSION_MAJOR || Minor != DB_VERSION_MINOR - || Patch != DB_VERSION_PATCH) + ) croak("\nBerkeleyDB needs compatible versions of libdb & db.h\n\tyou have db.h version %d.%d.%d and libdb version %d.%d.%d\n", DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH, Major, Minor, Patch) ;
Thanks for the patch Michael. A few minor issues with it - log_set_config needs BDB 4.7 or better and set_lk_max_lockers,set_lk_max_locks and set_lk_max_objects all need BDB 3.2.9 or better. I've added pre-processor conditionals to sort that out. After fixing that BerkeleyDB with your patch included passed my regression run with all official versions of BDB since 2.6. Regarding adding extra stuff to BerkeleyDB::Env->new() I've been thinking for a while that I really need an alternative interface that matches the BDB interface more closely. That would make adding new methods like this *much* easier. Finding the time to do that isn't going to happen soon though. Paul
Uploaded fixed version to CPAN (version 0.40) with this change.

Paul