From cd9696fc97fc06831c1edede62a063028f2afe75 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 13 May 2012 21:37:39 -0400 Subject: Encapsulate BDB environment inside new CDBEnv class Cleans up and organizes several scattered functions and variables related to the BDB env. Class CDBInit() existed to provide a guaranteed-via-C++-destructor cleanup of the db environment. A formal CDBEnv class provides all of this inside a single wrapper. --- src/db.cpp | 141 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 64 deletions(-) (limited to 'src/db.cpp') diff --git a/src/db.cpp b/src/db.cpp index 50f0891626..988c10caa2 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -26,14 +26,11 @@ unsigned int nWalletDBUpdated; // CDB // -CCriticalSection cs_db; -static bool fDbEnvInit = false; -bool fDetachDB = false; -DbEnv dbenv(0); +CDBEnv bitdb; map mapFileUseCount; static map mapDb; -static void EnvShutdown() +void CDBEnv::EnvShutdown() { if (!fDbEnvInit) return; @@ -50,18 +47,67 @@ static void EnvShutdown() DbEnv(0).remove(GetDataDir().string().c_str(), 0); } -class CDBInit +CDBEnv::CDBEnv() : dbenv(0) { -public: - CDBInit() - { - } - ~CDBInit() - { - EnvShutdown(); - } } -instance_of_cdbinit; + +CDBEnv::~CDBEnv() +{ + EnvShutdown(); +} + +void CDBEnv::Close() +{ + EnvShutdown(); +} + +bool CDBEnv::Open(boost::filesystem::path pathEnv_) +{ + if (fDbEnvInit) + return true; + + if (fShutdown) + return false; + + pathEnv = pathEnv_; + filesystem::path pathDataDir = pathEnv; + filesystem::path pathLogDir = pathDataDir / "database"; + filesystem::create_directory(pathLogDir); + filesystem::path pathErrorFile = pathDataDir / "db.log"; + printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str()); + + int nDbCache = GetArg("-dbcache", 25); + dbenv.set_lg_dir(pathLogDir.string().c_str()); + dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1); + dbenv.set_lg_bsize(1048576); + dbenv.set_lg_max(10485760); + dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_objects(10000); + dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug + dbenv.set_flags(DB_AUTO_COMMIT, 1); + dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); + dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); + int ret = dbenv.open(pathDataDir.string().c_str(), + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_RECOVER, + S_IRUSR | S_IWUSR); + if (ret > 0) + return error("CDB() : error %d opening database environment", ret); + + fDbEnvInit = true; + return true; +} + +void CDBEnv::CheckpointLSN(std::string strFile) +{ + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); +} CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) @@ -77,48 +123,16 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) nFlags |= DB_CREATE; { - LOCK(cs_db); - if (!fDbEnvInit) - { - if (fShutdown) - return; - filesystem::path pathDataDir = GetDataDir(); - filesystem::path pathLogDir = pathDataDir / "database"; - filesystem::create_directory(pathLogDir); - filesystem::path pathErrorFile = pathDataDir / "db.log"; - printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str()); - - int nDbCache = GetArg("-dbcache", 25); - dbenv.set_lg_dir(pathLogDir.string().c_str()); - dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1); - dbenv.set_lg_bsize(1048576); - dbenv.set_lg_max(10485760); - dbenv.set_lk_max_locks(10000); - dbenv.set_lk_max_objects(10000); - dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug - dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); - dbenv.set_flags(DB_AUTO_COMMIT, 1); - dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); - ret = dbenv.open(pathDataDir.string().c_str(), - DB_CREATE | - DB_INIT_LOCK | - DB_INIT_LOG | - DB_INIT_MPOOL | - DB_INIT_TXN | - DB_THREAD | - DB_RECOVER, - S_IRUSR | S_IWUSR); - if (ret > 0) - throw runtime_error(strprintf("CDB() : error %d opening database environment", ret)); - fDbEnvInit = true; - } + LOCK(bitdb.cs_db); + if (!bitdb.Open(GetDataDir())) + throw runtime_error("env open failed"); strFile = pszFile; ++mapFileUseCount[strFile]; pdb = mapDb[strFile]; if (pdb == NULL) { - pdb = new Db(&dbenv, 0); + pdb = new Db(&bitdb.dbenv, 0); ret = pdb->open(NULL, // Txn pointer pszFile, // Filename @@ -132,7 +146,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) delete pdb; pdb = NULL; { - LOCK(cs_db); + LOCK(bitdb.cs_db); --mapFileUseCount[strFile]; } strFile = ""; @@ -170,10 +184,10 @@ void CDB::Close() if (strFile == "blkindex.dat" && IsInitialBlockDownload()) nMinutes = 5; - dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0); + bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0); { - LOCK(cs_db); + LOCK(bitdb.cs_db); --mapFileUseCount[strFile]; } } @@ -181,7 +195,7 @@ void CDB::Close() void CloseDb(const string& strFile) { { - LOCK(cs_db); + LOCK(bitdb.cs_db); if (mapDb[strFile] != NULL) { // Close the database handle @@ -198,13 +212,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) while (!fShutdown) { { - LOCK(cs_db); + LOCK(bitdb.cs_db); if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0) { // Flush log data to the dat file CloseDb(strFile); - dbenv.txn_checkpoint(0, 0, 0); - dbenv.lsn_reset(strFile.c_str(), 0); + bitdb.CheckpointLSN(strFile); mapFileUseCount.erase(strFile); bool fSuccess = true; @@ -212,7 +225,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); - Db* pdbCopy = new Db(&dbenv, 0); + Db* pdbCopy = new Db(&bitdb.dbenv, 0); int ret = pdbCopy->open(NULL, // Txn pointer strFileRes.c_str(), // Filename @@ -270,10 +283,10 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) } if (fSuccess) { - Db dbA(&dbenv, 0); + Db dbA(&bitdb.dbenv, 0); if (dbA.remove(strFile.c_str(), NULL, 0)) fSuccess = false; - Db dbB(&dbenv, 0); + Db dbB(&bitdb.dbenv, 0); if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) fSuccess = false; } @@ -288,12 +301,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) } -void DBFlush(bool fShutdown) +void CDBEnv::Flush(bool fShutdown) { int64 nStart = GetTimeMillis(); // Flush log data to the actual data file // on all files that are not in use - printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); + printf("Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); if (!fDbEnvInit) return; { @@ -327,7 +340,7 @@ void DBFlush(bool fShutdown) if (mapFileUseCount.empty()) { dbenv.log_archive(&listp, DB_ARCH_REMOVE); - EnvShutdown(); + Close(); } } } -- cgit v1.2.3 From 8b1202c52c4d8f42c23b02a4cfdb097663e6e7b0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 14 May 2012 12:39:29 -0400 Subject: Remove unused nested BDB transaction support --- src/db.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/db.cpp') diff --git a/src/db.cpp b/src/db.cpp index 988c10caa2..21b1e0ae8e 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -170,9 +170,9 @@ void CDB::Close() { if (!pdb) return; - if (!vTxn.empty()) - vTxn.front()->abort(); - vTxn.clear(); + if (activeTxn) + activeTxn->abort(); + activeTxn = NULL; pdb = NULL; // Flush database activity from memory pool to disk log -- cgit v1.2.3 From 94e34fa0adb818baacdcb6408f0a92e07f3ce7df Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 14 May 2012 22:18:21 -0400 Subject: CDB::CDB: properly initialize activeTxn to NULL --- src/db.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/db.cpp') diff --git a/src/db.cpp b/src/db.cpp index 21b1e0ae8e..08b6614181 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -110,7 +110,8 @@ void CDBEnv::CheckpointLSN(std::string strFile) } -CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) +CDB::CDB(const char *pszFile, const char* pszMode) : + pdb(NULL), activeTxn(NULL) { int ret; if (pszFile == NULL) -- cgit v1.2.3 From ffe8b77a617efd802a9d4ba7e42b163fbd9a250b Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 18 May 2012 02:49:50 -0400 Subject: Further CDBEnv encapsulation work. --- src/db.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/db.cpp') diff --git a/src/db.cpp b/src/db.cpp index 08b6614181..f0addda918 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -27,8 +27,6 @@ unsigned int nWalletDBUpdated; // CDBEnv bitdb; -map mapFileUseCount; -static map mapDb; void CDBEnv::EnvShutdown() { @@ -129,8 +127,8 @@ CDB::CDB(const char *pszFile, const char* pszMode) : throw runtime_error("env open failed"); strFile = pszFile; - ++mapFileUseCount[strFile]; - pdb = mapDb[strFile]; + ++bitdb.mapFileUseCount[strFile]; + pdb = bitdb.mapDb[strFile]; if (pdb == NULL) { pdb = new Db(&bitdb.dbenv, 0); @@ -148,7 +146,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb = NULL; { LOCK(bitdb.cs_db); - --mapFileUseCount[strFile]; + --bitdb.mapFileUseCount[strFile]; } strFile = ""; throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret)); @@ -162,7 +160,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : fReadOnly = fTmp; } - mapDb[strFile] = pdb; + bitdb.mapDb[strFile] = pdb; } } } @@ -189,14 +187,14 @@ void CDB::Close() { LOCK(bitdb.cs_db); - --mapFileUseCount[strFile]; + --bitdb.mapFileUseCount[strFile]; } } -void CloseDb(const string& strFile) +void CDBEnv::CloseDb(const string& strFile) { { - LOCK(bitdb.cs_db); + LOCK(cs_db); if (mapDb[strFile] != NULL) { // Close the database handle @@ -214,12 +212,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) { { LOCK(bitdb.cs_db); - if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0) + if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { // Flush log data to the dat file - CloseDb(strFile); + bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); - mapFileUseCount.erase(strFile); + bitdb.mapFileUseCount.erase(strFile); bool fSuccess = true; printf("Rewriting %s...\n", strFile.c_str()); @@ -276,7 +274,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) if (fSuccess) { db.Close(); - CloseDb(strFile); + bitdb.CloseDb(strFile); if (pdbCopy->close(0)) fSuccess = false; delete pdbCopy; -- cgit v1.2.3