mirror of
https://github.com/monero-project/monero.git
synced 2025-12-05 20:40:22 -08:00
Merge pull request #10179
9e57f9b blockchain_prune: check DB version (jeffro256)
This commit is contained in:
@@ -53,6 +53,8 @@ static std::string db_path;
|
|||||||
static uint64_t records_per_sync = 16 * 65536;
|
static uint64_t records_per_sync = 16 * 65536;
|
||||||
static const size_t slack = 512 * 1024 * 1024;
|
static const size_t slack = 512 * 1024 * 1024;
|
||||||
|
|
||||||
|
static constexpr uint32_t MAX_SUPPORTED_DB_VERSION = 5;
|
||||||
|
|
||||||
static std::vector<bool> is_v1;
|
static std::vector<bool> is_v1;
|
||||||
|
|
||||||
static std::error_code replace_file(const boost::filesystem::path& replacement_name, const boost::filesystem::path& replaced_name)
|
static std::error_code replace_file(const boost::filesystem::path& replacement_name, const boost::filesystem::path& replaced_name)
|
||||||
@@ -158,6 +160,46 @@ static bool resize_point(size_t &nrecords, MDB_env *env, MDB_txn **txn, size_t &
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t get_blockchain_db_version(MDB_env *env)
|
||||||
|
{
|
||||||
|
MDB_dbi properties_dbi;
|
||||||
|
MDB_txn *txn;
|
||||||
|
bool tx_active = false;
|
||||||
|
int rc;
|
||||||
|
MDB_val k;
|
||||||
|
MDB_val v;
|
||||||
|
uint32_t db_version = std::numeric_limits<uint32_t>::max();
|
||||||
|
|
||||||
|
const epee::misc_utils::auto_scope_leave_caller txn_dtor = epee::misc_utils::create_scope_leave_handler([&](){
|
||||||
|
if (tx_active) mdb_txn_abort(txn);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup tx and database index
|
||||||
|
rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
|
||||||
|
if (rc) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(rc)));
|
||||||
|
tx_active = true;
|
||||||
|
rc = mdb_dbi_open(txn, "properties", /*flags=*/0, &properties_dbi);
|
||||||
|
if (rc) throw std::runtime_error("Failed to open LMDB properties dbi: " + std::string(mdb_strerror(rc)));
|
||||||
|
mdb_set_compare(txn, properties_dbi, BlockchainLMDB::compare_string);
|
||||||
|
|
||||||
|
// Fetch version
|
||||||
|
char VERSION_KEY[] = "version";
|
||||||
|
k.mv_data = reinterpret_cast<void*>(VERSION_KEY);
|
||||||
|
k.mv_size = sizeof(VERSION_KEY); // yes, this includes the null terminator
|
||||||
|
v = {};
|
||||||
|
rc = mdb_get(txn, properties_dbi, &k, &v);
|
||||||
|
if (rc) throw std::runtime_error("Failed to get version from properties table: " + std::string(mdb_strerror(rc)));
|
||||||
|
if (v.mv_data == nullptr || v.mv_size != sizeof(db_version))
|
||||||
|
throw std::runtime_error("Fetched version entry is wrong size");
|
||||||
|
memcpy(&db_version, v.mv_data, sizeof(db_version));
|
||||||
|
|
||||||
|
// Close tx
|
||||||
|
tx_active = false;
|
||||||
|
mdb_txn_commit(txn);
|
||||||
|
|
||||||
|
return db_version;
|
||||||
|
}
|
||||||
|
|
||||||
static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned int flags, unsigned int putflags, int (*cmp)(const MDB_val*, const MDB_val*)=0, void (*f)(const MDB_val&, const MDB_val&) = 0)
|
static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned int flags, unsigned int putflags, int (*cmp)(const MDB_val*, const MDB_val*)=0, void (*f)(const MDB_val&, const MDB_val&) = 0)
|
||||||
{
|
{
|
||||||
MDB_dbi dbi0, dbi1;
|
MDB_dbi dbi0, dbi1;
|
||||||
@@ -633,10 +675,23 @@ int main(int argc, char* argv[])
|
|||||||
core_storage[1]->blockchain.deinit();
|
core_storage[1]->blockchain.deinit();
|
||||||
core_storage[1].reset(NULL);
|
core_storage[1].reset(NULL);
|
||||||
|
|
||||||
MINFO("Pruning...");
|
MINFO("Opening source database...");
|
||||||
MDB_env *env0 = NULL, *env1 = NULL;
|
MDB_env *env0 = NULL, *env1 = NULL;
|
||||||
open(env0, paths[0], db_flags, true);
|
open(env0, paths[0], db_flags, true);
|
||||||
|
const uint32_t db_version = get_blockchain_db_version(env0);
|
||||||
|
MDEBUG("Blockchain DB has version " << db_version);
|
||||||
|
if (db_version > MAX_SUPPORTED_DB_VERSION)
|
||||||
|
{
|
||||||
|
MERROR("Source database has unrecognized blockchain DB version " << db_version
|
||||||
|
<< ". Code for blockchain_prune may need to be updated.");
|
||||||
|
close(env0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MINFO("Opening target database...");
|
||||||
open(env1, paths[1], db_flags, false);
|
open(env1, paths[1], db_flags, false);
|
||||||
|
|
||||||
|
MINFO("Copying unpruned tables...");
|
||||||
copy_table(env0, env1, "blocks", MDB_INTEGERKEY, 0);
|
copy_table(env0, env1, "blocks", MDB_INTEGERKEY, 0);
|
||||||
copy_table(env0, env1, "block_info", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
copy_table(env0, env1, "block_info", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
||||||
copy_table(env0, env1, "block_heights", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, 0, BlockchainLMDB::compare_hash32);
|
copy_table(env0, env1, "block_heights", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, 0, BlockchainLMDB::compare_hash32);
|
||||||
@@ -656,11 +711,13 @@ int main(int argc, char* argv[])
|
|||||||
copy_table(env0, env1, "properties", 0, 0, BlockchainLMDB::compare_string);
|
copy_table(env0, env1, "properties", 0, 0, BlockchainLMDB::compare_string);
|
||||||
if (already_pruned)
|
if (already_pruned)
|
||||||
{
|
{
|
||||||
|
MINFO("Copying already-pruned tables...");
|
||||||
copy_table(env0, env1, "txs_prunable", MDB_INTEGERKEY, 0, BlockchainLMDB::compare_uint64);
|
copy_table(env0, env1, "txs_prunable", MDB_INTEGERKEY, 0, BlockchainLMDB::compare_uint64);
|
||||||
copy_table(env0, env1, "txs_prunable_tip", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
copy_table(env0, env1, "txs_prunable_tip", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_uint64);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MINFO("Pruning...");
|
||||||
prune(env0, env1);
|
prune(env0, env1);
|
||||||
}
|
}
|
||||||
close(env1);
|
close(env1);
|
||||||
|
|||||||
Reference in New Issue
Block a user