From ba035bf827537ada447a51f0954679e247c10ff2 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 15 Jun 2019 09:49:28 +0000 Subject: [PATCH] db_lmdb: commit pruning txn at checkpoints to avoid errors when the txn is too large --- src/blockchain_db/lmdb/db_lmdb.cpp | 51 +++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index f05eb0f30..d0fd787db 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -1953,7 +1953,7 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) TIME_MEASURE_START(t); - size_t n_total_records = 0, n_prunable_records = 0, n_pruned_records = 0; + size_t n_total_records = 0, n_prunable_records = 0, n_pruned_records = 0, commit_counter = 0; uint64_t n_bytes = 0; mdb_txn_safe txn; @@ -2056,6 +2056,7 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) { MDEBUG("Pruning at height " << block_height << "/" << blockchain_height); ++n_pruned_records; + ++commit_counter; n_bytes += k.mv_size + v.mv_size; result = mdb_cursor_del(c_txs_prunable, 0); if (result) @@ -2065,6 +2066,25 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) result = mdb_cursor_del(c_txs_prunable_tip, 0); if (result) throw0(DB_ERROR(lmdb_error("Failed to delete transaction tip data: ", result).c_str())); + + if (mode != prune_mode_check && commit_counter >= 4096) + { + MDEBUG("Committing txn at checkpoint..."); + txn.commit(); + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_pruned, &c_txs_pruned); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_pruned: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable, &c_txs_prunable); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable_tip, &c_txs_prunable_tip); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable_tip: ", result).c_str())); + commit_counter = 0; + } } } } @@ -2134,6 +2154,7 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) result = mdb_cursor_del(c_txs_prunable, 0); if (result) throw0(DB_ERROR(lmdb_error("Failed to delete transaction prunable data: ", result).c_str())); + ++commit_counter; } } } @@ -2150,6 +2171,34 @@ bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) ", seed " << epee::string_tools::to_string_hex(pruning_seed)); } } + + if (mode != prune_mode_check && commit_counter >= 4096) + { + MDEBUG("Committing txn at checkpoint..."); + txn.commit(); + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_pruned, &c_txs_pruned); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_pruned: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable, &c_txs_prunable); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable_tip, &c_txs_prunable_tip); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable_tip: ", result).c_str())); + result = mdb_cursor_open(txn, m_tx_indices, &c_tx_indices); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for tx_indices: ", result).c_str())); + MDB_val val; + val.mv_size = sizeof(ti); + val.mv_data = (void *)&ti; + result = mdb_cursor_get(c_tx_indices, (MDB_val*)&zerokval, &val, MDB_GET_BOTH); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to restore cursor for tx_indices: ", result).c_str())); + commit_counter = 0; + } } mdb_cursor_close(c_tx_indices); }