[rhmessaging-commits] rhmessaging commits: r4133 - store/trunk/cpp/lib.
rhmessaging-commits at lists.jboss.org
rhmessaging-commits at lists.jboss.org
Tue Jul 20 13:07:24 EDT 2010
Author: kpvdr
Date: 2010-07-20 13:07:24 -0400 (Tue, 20 Jul 2010)
New Revision: 4133
Modified:
store/trunk/cpp/lib/MessageStoreImpl.cpp
store/trunk/cpp/lib/MessageStoreImpl.h
Log:
Bug 614944 - "qpidd broker crash in mrg::msgstore::TxnCtxt::abort() -> DbTxn::abort()": Fix part 1, which improves the exception handling so that there is no throw within a catch. This will not change the probability of occurance of this bug, but the logs and exception message outcome will be different.
Modified: store/trunk/cpp/lib/MessageStoreImpl.cpp
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.cpp 2010-07-20 16:51:16 UTC (rev 4132)
+++ store/trunk/cpp/lib/MessageStoreImpl.cpp 2010-07-20 17:07:24 UTC (rev 4133)
@@ -306,57 +306,61 @@
void MessageStoreImpl::init()
{
- journal::jdir::create_dir(getBdbBaseDir());
+ try {
+ journal::jdir::create_dir(getBdbBaseDir());
- try {
- dbenv.reset(new DbEnv(0));
- dbenv->set_errpfx("msgstore");
- dbenv->set_lg_regionmax(256000); // default = 65000
- dbenv->open(getBdbBaseDir().c_str(), DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON | DB_RECOVER, 0);
- } catch (const DbException& e) {
- if (e.get_errno() == DB_VERSION_MISMATCH)
- THROW_STORE_EXCEPTION_2("Database environment mismatch: This version of bd4 does not match that which created the store database. "
- "(If recovery is not important, delete the contents of the store directory. Otherwise, try upgrading the database using "
- "db_upgrade or using db_recover - but the db4-utils package must also be installed to use these utilities.)", e);
- THROW_STORE_EXCEPTION_2("Error opening environment", e);
- }
+ dbenv.reset(new DbEnv(0));
+ dbenv->set_errpfx("msgstore");
+ dbenv->set_lg_regionmax(256000); // default = 65000
+ dbenv->open(getBdbBaseDir().c_str(), DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON | DB_RECOVER, 0);
- TxnCtxt txn;
- try {
- // Databases are constructed here instead of the constructor so that the DB_RECOVER flag can be used
- // against the database environment. Recover can only be performed if no databases have been created
- // against the environment at the time of recovery, as recovery invalidates the environment.
- queueDb.reset(new Db(dbenv.get(), 0));
- configDb.reset(new Db(dbenv.get(), 0));
- exchangeDb.reset(new Db(dbenv.get(), 0));
- mappingDb.reset(new Db(dbenv.get(), 0));
- bindingDb.reset(new Db(dbenv.get(), 0));
- generalDb.reset(new Db(dbenv.get(), 0));
+ // Databases are constructed here instead of the constructor so that the DB_RECOVER flag can be used
+ // against the database environment. Recover can only be performed if no databases have been created
+ // against the environment at the time of recovery, as recovery invalidates the environment.
+ queueDb.reset(new Db(dbenv.get(), 0));
+ dbs.push_back(queueDb);
+ configDb.reset(new Db(dbenv.get(), 0));
+ dbs.push_back(configDb);
+ exchangeDb.reset(new Db(dbenv.get(), 0));
+ dbs.push_back(exchangeDb);
+ mappingDb.reset(new Db(dbenv.get(), 0));
+ dbs.push_back(mappingDb);
+ bindingDb.reset(new Db(dbenv.get(), 0));
+ dbs.push_back(bindingDb);
+ generalDb.reset(new Db(dbenv.get(), 0));
+ dbs.push_back(generalDb);
- txn.begin(dbenv.get(), false);
- open(queueDb, txn.get(), "queues.db", false);
- open(configDb, txn.get(), "config.db", false);
- open(exchangeDb, txn.get(), "exchanges.db", false);
- open(mappingDb, txn.get(), "mappings.db", true);
- open(bindingDb, txn.get(), "bindings.db", true);
- open(generalDb, txn.get(), "general.db", false);
- tplStorePtr.reset(new TplJournalImpl(timer, "TplStore", getTplBaseDir(), "tpl", defJournalGetEventsTimeout, defJournalFlushTimeout, agent));
- txn.commit();
- } catch (const journal::jexception& e) {
- QPID_LOG(error, "Journal Exception occurred while initializing store: " << e);
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error opening tplStore instance", e.what());
- } catch (const DbException& e) {
- QPID_LOG(error, "BDB exception occurred while initializing store: " << e.what());
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error opening databases", e);
- } catch (...) {
- QPID_LOG(error, "Unknown exception occurred while initializing store.");
- txn.abort();
- throw;
- }
+ TxnCtxt txn;
+ txn.begin(dbenv.get(), false);
+ try {
+ open(queueDb, txn.get(), "queues.db", false);
+ open(configDb, txn.get(), "config.db", false);
+ open(exchangeDb, txn.get(), "exchanges.db", false);
+ open(mappingDb, txn.get(), "mappings.db", true);
+ open(bindingDb, txn.get(), "bindings.db", true);
+ open(generalDb, txn.get(), "general.db", false);
+ txn.commit();
+ } catch (...) { txn.abort(); throw; }
- isInit = true;
+ tplStorePtr.reset(new TplJournalImpl(timer, "TplStore", getTplBaseDir(), "tpl", defJournalGetEventsTimeout, defJournalFlushTimeout, agent));
+ isInit = true;
+ } catch (const DbException& e) {
+ if (e.get_errno() == DB_VERSION_MISMATCH)
+ {
+ QPID_LOG(error, "Database environment mismatch: This version of db4 does not match that which created the store database.: " << e.what());
+ THROW_STORE_EXCEPTION_2("Database environment mismatch: This version of db4 does not match that which created the store database. "
+ "(If recovery is not important, delete the contents of the store directory. Otherwise, try upgrading the database using "
+ "db_upgrade or using db_recover - but the db4-utils package must also be installed to use these utilities.)", e);
+ }
+ QPID_LOG(error, "BDB exception occurred while initializing store: " << e.what());
+ THROW_STORE_EXCEPTION_2("BDB exception occurred while initializing store", e);
+ } catch (const journal::jexception& e) {
+ QPID_LOG(error, "Journal Exception occurred while initializing store: " << e);
+ THROW_STORE_EXCEPTION_2("Journal Exception occurred while initializing store", e.what());
+ } catch (...) {
+ QPID_LOG(error, "Unknown exception occurred while initializing store.");
+ throw;
+ }
}
void MessageStoreImpl::finalize()
@@ -389,20 +393,19 @@
THROW_STORE_EXCEPTION(oss.str());
}
}
- for (std::list<db_ptr >::iterator i = dbs.begin(); i != dbs.end(); i++) {
- (*i)->close(0);
- }
+ closeDbs();
dbs.clear();
if (tplStorePtr->is_ready()) tplStorePtr->stop(true);
dbenv->close(0);
+ isInit = false;
}
std::ostringstream oss;
oss << storeDir << "/" << storeTopLevelDir;
if (pushDownStoreFiles) {
QPID_LOG(notice, "Store directory " << oss.str() << " was pushed down into directory " << mrg::journal::jdir::push_down(storeDir, storeTopLevelDir, "cluster") << ".");
} else {
+ mrg::journal::jdir::delete_dir(oss.str().c_str());
QPID_LOG(notice, "Store directory " << oss.str() << " was truncated.");
- mrg::journal::jdir::delete_dir(oss.str().c_str());
}
init();
}
@@ -425,16 +428,21 @@
{
if(dupKey) db->set_flags(DB_DUPSORT);
db->open(txn, file, 0, DB_BTREE, DB_CREATE | DB_THREAD, 0);
- dbs.push_back(db);
}
+void MessageStoreImpl::closeDbs()
+{
+ for (std::list<db_ptr >::iterator i = dbs.begin(); i != dbs.end(); i++) {
+ (*i)->close(0);
+ }
+ dbs.clear();
+}
+
MessageStoreImpl::~MessageStoreImpl()
{
finalize();
try {
- for (std::list<db_ptr >::iterator i = dbs.begin(); i != dbs.end(); i++) {
- (*i)->close(0);
- }
+ closeDbs();
} catch (const DbException& e) {
QPID_LOG(error, "Error closing BDB databases: " << e.what());
} catch (const journal::jexception& e) {
Modified: store/trunk/cpp/lib/MessageStoreImpl.h
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.h 2010-07-20 16:51:16 UTC (rev 4132)
+++ store/trunk/cpp/lib/MessageStoreImpl.h 2010-07-20 17:07:24 UTC (rev 4133)
@@ -240,6 +240,7 @@
DbTxn* txn,
const char* file,
bool dupKey);
+ void closeDbs();
// journal functions
void createJrnlQueue(const qpid::broker::PersistableQueue& queue);
More information about the rhmessaging-commits
mailing list