diff options
Diffstat (limited to 'src/blockchain_db/lmdb/db_lmdb.h')
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.h | 90 |
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 |