aboutsummaryrefslogtreecommitdiff
path: root/src/blockchain_db/lmdb/db_lmdb.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/blockchain_db/lmdb/db_lmdb.h')
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h90
1 files changed, 38 insertions, 52 deletions
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index 8f1e07e0d..ec552a0f6 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -26,6 +26,8 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
+#include <atomic>
+
#include "blockchain_db/blockchain_db.h"
#include "cryptonote_protocol/blobdatatype.h" // for type blobdata
@@ -36,63 +38,16 @@ namespace cryptonote
struct mdb_txn_safe
{
- mdb_txn_safe() : m_txn(NULL) { }
- ~mdb_txn_safe()
- {
- LOG_PRINT_L3("mdb_txn_safe: destructor");
- if (m_txn != NULL)
- {
- if (m_batch_txn) // this is a batch txn and should have been handled before this point for safety
- {
- LOG_PRINT_L0("WARNING: mdb_txn_safe: m_txn is a batch txn and it's not NULL in destructor - calling mdb_txn_abort()");
- }
- else
- {
- // Example of when this occurs: a lookup fails, so a read-only txn is
- // aborted through this destructor. However, successful read-only txns
- // ideally should have been committed when done and not end up here.
- //
- // NOTE: not sure if this is ever reached for a non-batch write
- // transaction, but it's probably not ideal if it did.
- LOG_PRINT_L3("mdb_txn_safe: m_txn not NULL in destructor - calling mdb_txn_abort()");
- }
- mdb_txn_abort(m_txn);
- }
- }
+ mdb_txn_safe();
+ ~mdb_txn_safe();
- void commit(std::string message = "")
- {
- if (message.size() == 0)
- {
- message = "Failed to commit a transaction to the db";
- }
-
- if (mdb_txn_commit(m_txn))
- {
- m_txn = NULL;
- LOG_PRINT_L0(message);
- throw DB_ERROR(message.c_str());
- }
- m_txn = NULL;
- }
+ void commit(std::string message = "");
// This should only be needed for batch transaction which must be ensured to
// be aborted before mdb_env_close, not after. So we can't rely on
// BlockchainLMDB destructor to call mdb_txn_safe destructor, as that's too late
// to properly abort, since mdb_env_close would have been called earlier.
- void abort()
- {
- LOG_PRINT_L3("mdb_txn_safe: abort()");
- if(m_txn != NULL)
- {
- mdb_txn_abort(m_txn);
- m_txn = NULL;
- }
- else
- {
- LOG_PRINT_L0("WARNING: mdb_txn_safe: abort() called, but m_txn is NULL");
- }
- }
+ void abort();
operator MDB_txn*()
{
@@ -104,11 +59,34 @@ struct mdb_txn_safe
return &m_txn;
}
+ uint64_t num_active_tx();
+
+ static void prevent_new_txns();
+ static void wait_no_active_txns();
+ static void allow_new_txns();
+
MDB_txn* m_txn;
bool m_batch_txn = false;
+ static std::atomic<uint64_t> num_active_txns;
+
+ // could use a mutex here, but this should be sufficient.
+ static std::atomic_flag creation_gate;
};
+// If m_batch_active is set, a batch transaction exists beyond this class, such
+// as a batch import with verification enabled, or possibly (later) a batch
+// network sync.
+//
+// For some of the lookup methods, such as get_block_timestamp(), tx_exists(),
+// and get_tx(), when m_batch_active is set, the lookup uses the batch
+// transaction. This isn't only because the transaction is available, but it's
+// necessary so that lookups include the database updates only present in the
+// current batch write.
+//
+// A regular network sync without batch writes is expected to open a new read
+// transaction, as those lookups are part of the validation done prior to the
+// write for block and tx data, so no write transaction is open at the time.
class BlockchainLMDB : public BlockchainDB
{
public:
@@ -221,6 +199,10 @@ public:
virtual void pop_block(block& blk, std::vector<transaction>& txs);
private:
+ void do_resize();
+
+ bool need_resize();
+
virtual void add_block( const block& blk
, const size_t& block_size
, const difficulty_type& cumulative_difficulty
@@ -305,10 +287,14 @@ private:
uint64_t m_num_outputs;
std::string m_folder;
mdb_txn_safe* m_write_txn; // may point to either a short-lived txn or a batch txn
- mdb_txn_safe m_write_batch_txn; // persist batch txn outside of BlockchainLMDB
+ mdb_txn_safe* m_write_batch_txn; // persist batch txn outside of BlockchainLMDB
bool m_batch_transactions; // support for batch transactions
bool m_batch_active; // whether batch transaction is in progress
+
+ constexpr static uint64_t DEFAULT_MAPSIZE = 1 << 30;
+ constexpr static float RESIZE_PERCENT = 0.8f;
+ constexpr static float RESIZE_FACTOR = 1.5f;
};
} // namespace cryptonote