Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/db.cpp
Show All 40 Lines | void CDBEnv::EnvShutdown() { | ||||
} | } | ||||
if (!fMockDb) { | if (!fMockDb) { | ||||
DbEnv(uint32_t(0)).remove(strPath.c_str(), 0); | DbEnv(uint32_t(0)).remove(strPath.c_str(), 0); | ||||
} | } | ||||
} | } | ||||
void CDBEnv::Reset() { | void CDBEnv::Reset() { | ||||
delete dbenv; | dbenv.reset(new DbEnv(DB_CXX_NO_EXCEPTIONS)); | ||||
dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS); | |||||
fDbEnvInit = false; | fDbEnvInit = false; | ||||
fMockDb = false; | fMockDb = false; | ||||
} | } | ||||
CDBEnv::CDBEnv() : dbenv(nullptr) { | CDBEnv::CDBEnv() { | ||||
Reset(); | Reset(); | ||||
} | } | ||||
CDBEnv::~CDBEnv() { | CDBEnv::~CDBEnv() { | ||||
EnvShutdown(); | EnvShutdown(); | ||||
delete dbenv; | |||||
dbenv = nullptr; | |||||
} | } | ||||
void CDBEnv::Close() { | void CDBEnv::Close() { | ||||
EnvShutdown(); | EnvShutdown(); | ||||
} | } | ||||
bool CDBEnv::Open(const fs::path &pathIn) { | bool CDBEnv::Open(const fs::path &pathIn) { | ||||
if (fDbEnvInit) { | if (fDbEnvInit) { | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
CDBEnv::VerifyResult CDBEnv::Verify(const std::string &strFile, | CDBEnv::VerifyResult CDBEnv::Verify(const std::string &strFile, | ||||
recoverFunc_type recoverFunc, | recoverFunc_type recoverFunc, | ||||
std::string &out_backup_filename) { | std::string &out_backup_filename) { | ||||
LOCK(cs_db); | LOCK(cs_db); | ||||
assert(mapFileUseCount.count(strFile) == 0); | assert(mapFileUseCount.count(strFile) == 0); | ||||
Db db(dbenv, 0); | Db db(dbenv.get(), 0); | ||||
int result = db.verify(strFile.c_str(), nullptr, nullptr, 0); | int result = db.verify(strFile.c_str(), nullptr, nullptr, 0); | ||||
if (result == 0) { | if (result == 0) { | ||||
return VERIFY_OK; | return VERIFY_OK; | ||||
} else if (recoverFunc == nullptr) { | } else if (recoverFunc == nullptr) { | ||||
return RECOVER_FAIL; | return RECOVER_FAIL; | ||||
} | } | ||||
// Try to recover: | // Try to recover: | ||||
Show All 26 Lines | bool CDB::Recover(const std::string &filename, void *callbackDataIn, | ||||
std::vector<CDBEnv::KeyValPair> salvagedData; | std::vector<CDBEnv::KeyValPair> salvagedData; | ||||
bool fSuccess = bitdb.Salvage(newFilename, true, salvagedData); | bool fSuccess = bitdb.Salvage(newFilename, true, salvagedData); | ||||
if (salvagedData.empty()) { | if (salvagedData.empty()) { | ||||
LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename); | LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename); | ||||
return false; | return false; | ||||
} | } | ||||
LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); | LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); | ||||
std::unique_ptr<Db> pdbCopy(new Db(bitdb.dbenv, 0)); | std::unique_ptr<Db> pdbCopy(new Db(bitdb.dbenv.get(), 0)); | ||||
int ret = pdbCopy->open(nullptr, // Txn pointer | int ret = pdbCopy->open(nullptr, // Txn pointer | ||||
filename.c_str(), // Filename | filename.c_str(), // Filename | ||||
"main", // Logical db name | "main", // Logical db name | ||||
DB_BTREE, // Database type | DB_BTREE, // Database type | ||||
DB_CREATE, // Flags | DB_CREATE, // Flags | ||||
0); | 0); | ||||
if (ret > 0) { | if (ret > 0) { | ||||
LogPrintf("Cannot create database file %s\n", filename); | LogPrintf("Cannot create database file %s\n", filename); | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | bool CDBEnv::Salvage(const std::string &strFile, bool fAggressive, | ||||
u_int32_t flags = DB_SALVAGE; | u_int32_t flags = DB_SALVAGE; | ||||
if (fAggressive) { | if (fAggressive) { | ||||
flags |= DB_AGGRESSIVE; | flags |= DB_AGGRESSIVE; | ||||
} | } | ||||
std::stringstream strDump; | std::stringstream strDump; | ||||
Db db(dbenv, 0); | Db db(dbenv.get(), 0); | ||||
int result = db.verify(strFile.c_str(), nullptr, &strDump, flags); | int result = db.verify(strFile.c_str(), nullptr, &strDump, flags); | ||||
if (result == DB_VERIFY_BAD) { | if (result == DB_VERIFY_BAD) { | ||||
LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data " | LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data " | ||||
"may not be recoverable.\n"); | "may not be recoverable.\n"); | ||||
if (!fAggressive) { | if (!fAggressive) { | ||||
LogPrintf("CDBEnv::Salvage: Rerun with aggressive mode to ignore " | LogPrintf("CDBEnv::Salvage: Rerun with aggressive mode to ignore " | ||||
"errors and continue.\n"); | "errors and continue.\n"); | ||||
return false; | return false; | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (fCreate) { | ||||
LOCK(env->cs_db); | LOCK(env->cs_db); | ||||
if (!env->Open(GetDataDir())) { | if (!env->Open(GetDataDir())) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"CDB: Failed to open database environment."); | "CDB: Failed to open database environment."); | ||||
} | } | ||||
pdb = env->mapDb[strFilename]; | pdb = env->mapDb[strFilename]; | ||||
if (pdb == nullptr) { | if (pdb == nullptr) { | ||||
std::unique_ptr<Db> pdb_temp(new Db(env->dbenv, 0)); | std::unique_ptr<Db> pdb_temp(new Db(env->dbenv.get(), 0)); | ||||
bool fMockDb = env->IsMock(); | bool fMockDb = env->IsMock(); | ||||
if (fMockDb) { | if (fMockDb) { | ||||
DbMpoolFile *mpf = pdb_temp->get_mpf(); | DbMpoolFile *mpf = pdb_temp->get_mpf(); | ||||
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); | ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); | ||||
if (ret != 0) { | if (ret != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
strprintf("CDB: Failed to configure for no temp file " | strprintf("CDB: Failed to configure for no temp file " | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | while (true) { | ||||
env->mapFileUseCount.erase(strFile); | env->mapFileUseCount.erase(strFile); | ||||
bool fSuccess = true; | bool fSuccess = true; | ||||
LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile); | LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile); | ||||
std::string strFileRes = strFile + ".rewrite"; | std::string strFileRes = strFile + ".rewrite"; | ||||
{ | { | ||||
// surround usage of db with extra {} | // surround usage of db with extra {} | ||||
CDB db(dbw, "r"); | CDB db(dbw, "r"); | ||||
Db *pdbCopy = new Db(env->dbenv, 0); | std::unique_ptr<Db> pdbCopy = | ||||
std::unique_ptr<Db>(new Db(env->dbenv.get(), 0)); | |||||
int ret = pdbCopy->open(nullptr, // Txn pointer | int ret = pdbCopy->open(nullptr, // Txn pointer | ||||
strFileRes.c_str(), // Filename | strFileRes.c_str(), // Filename | ||||
"main", // Logical db name | "main", // Logical db name | ||||
DB_BTREE, // Database type | DB_BTREE, // Database type | ||||
DB_CREATE, // Flags | DB_CREATE, // Flags | ||||
0); | 0); | ||||
if (ret > 0) { | if (ret > 0) { | ||||
Show All 38 Lines | while (true) { | ||||
} | } | ||||
} | } | ||||
if (fSuccess) { | if (fSuccess) { | ||||
db.Close(); | db.Close(); | ||||
env->CloseDb(strFile); | env->CloseDb(strFile); | ||||
if (pdbCopy->close(0)) { | if (pdbCopy->close(0)) { | ||||
fSuccess = false; | fSuccess = false; | ||||
} | } | ||||
delete pdbCopy; | |||||
} | } | ||||
} | } | ||||
if (fSuccess) { | if (fSuccess) { | ||||
Db dbA(env->dbenv, 0); | Db dbA(env->dbenv.get(), 0); | ||||
if (dbA.remove(strFile.c_str(), nullptr, 0)) { | if (dbA.remove(strFile.c_str(), nullptr, 0)) { | ||||
fSuccess = false; | fSuccess = false; | ||||
} | } | ||||
Db dbB(env->dbenv, 0); | Db dbB(env->dbenv.get(), 0); | ||||
if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), | if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), | ||||
0)) { | 0)) { | ||||
fSuccess = false; | fSuccess = false; | ||||
} | } | ||||
} | } | ||||
if (!fSuccess) { | if (!fSuccess) { | ||||
LogPrintf( | LogPrintf( | ||||
"CDB::Rewrite: Failed to rewrite database file %s\n", | "CDB::Rewrite: Failed to rewrite database file %s\n", | ||||
▲ Show 20 Lines • Show All 153 Lines • Show Last 20 Lines |