Fix use of rtxn without a mdb_txn_safe wrapper

This commit is contained in:
Howard Chu 2022-06-07 20:27:11 +01:00
parent b6a029f222
commit c0f3c5b577
No known key found for this signature in database
GPG Key ID: FD2A70B44AB11BA7
2 changed files with 55 additions and 47 deletions

View File

@ -1883,10 +1883,11 @@ public:
} }
virtual ~db_txn_guard() virtual ~db_txn_guard()
{ {
if (active)
stop(); stop();
} }
void stop() void stop()
{
if (active)
{ {
if (readonly) if (readonly)
db->block_rtxn_stop(); db->block_rtxn_stop();
@ -1894,6 +1895,7 @@ public:
db->block_wtxn_stop(); db->block_wtxn_stop();
active = false; active = false;
} }
}
void abort() void abort()
{ {
if (readonly) if (readonly)

View File

@ -465,6 +465,32 @@ void mdb_txn_safe::increment_txns(int i)
num_active_txns += i; num_active_txns += i;
} }
#define TXN_PREFIX(flags); \
mdb_txn_safe auto_txn; \
mdb_txn_safe* txn_ptr = &auto_txn; \
if (m_batch_active) \
txn_ptr = m_write_txn; \
else \
{ \
if (auto mdb_res = lmdb_txn_begin(m_env, NULL, flags, auto_txn)) \
throw0(DB_ERROR(lmdb_error(std::string("Failed to create a transaction for the db in ")+__FUNCTION__+": ", mdb_res).c_str())); \
} \
#define TXN_PREFIX_RDONLY() \
MDB_txn *m_txn; \
mdb_txn_cursors *m_cursors; \
mdb_txn_safe auto_txn; \
bool my_rtxn = block_rtxn_start(&m_txn, &m_cursors); \
if (my_rtxn) auto_txn.m_tinfo = m_tinfo.get(); \
else auto_txn.uncheck()
#define TXN_POSTFIX_RDONLY()
#define TXN_POSTFIX_SUCCESS() \
do { \
if (! m_batch_active) \
auto_txn.commit(); \
} while(0)
void lmdb_resized(MDB_env *env, int isactive) void lmdb_resized(MDB_env *env, int isactive)
{ {
mdb_txn_safe::prevent_new_txns(); mdb_txn_safe::prevent_new_txns();
@ -713,9 +739,8 @@ uint64_t BlockchainLMDB::get_estimated_batch_size(uint64_t batch_num_blocks, uin
} }
else else
{ {
MDB_txn *rtxn; {
mdb_txn_cursors *rcurs; TXN_PREFIX_RDONLY();
bool my_rtxn = block_rtxn_start(&rtxn, &rcurs);
for (uint64_t block_num = block_start; block_num <= block_stop; ++block_num) for (uint64_t block_num = block_start; block_num <= block_stop; ++block_num)
{ {
// we have access to block weight, which will be greater or equal to block size, // we have access to block weight, which will be greater or equal to block size,
@ -727,7 +752,7 @@ uint64_t BlockchainLMDB::get_estimated_batch_size(uint64_t batch_num_blocks, uin
// some blocks were to be skipped for being outliers. // some blocks were to be skipped for being outliers.
++num_blocks_used; ++num_blocks_used;
} }
if (my_rtxn) block_rtxn_stop(); }
avg_block_size = total_block_size / (num_blocks_used ? num_blocks_used : 1); avg_block_size = total_block_size / (num_blocks_used ? num_blocks_used : 1);
MDEBUG("average block size across recent " << num_blocks_used << " blocks: " << avg_block_size); MDEBUG("average block size across recent " << num_blocks_used << " blocks: " << avg_block_size);
} }
@ -1678,32 +1703,6 @@ void BlockchainLMDB::unlock()
check_open(); check_open();
} }
#define TXN_PREFIX(flags); \
mdb_txn_safe auto_txn; \
mdb_txn_safe* txn_ptr = &auto_txn; \
if (m_batch_active) \
txn_ptr = m_write_txn; \
else \
{ \
if (auto mdb_res = lmdb_txn_begin(m_env, NULL, flags, auto_txn)) \
throw0(DB_ERROR(lmdb_error(std::string("Failed to create a transaction for the db in ")+__FUNCTION__+": ", mdb_res).c_str())); \
} \
#define TXN_PREFIX_RDONLY() \
MDB_txn *m_txn; \
mdb_txn_cursors *m_cursors; \
mdb_txn_safe auto_txn; \
bool my_rtxn = block_rtxn_start(&m_txn, &m_cursors); \
if (my_rtxn) auto_txn.m_tinfo = m_tinfo.get(); \
else auto_txn.uncheck()
#define TXN_POSTFIX_RDONLY()
#define TXN_POSTFIX_SUCCESS() \
do { \
if (! m_batch_active) \
auto_txn.commit(); \
} while(0)
// The below two macros are for DB access within block add/remove, whether // The below two macros are for DB access within block add/remove, whether
// regular batch txn is in use or not. m_write_txn is used as a batch txn, even // regular batch txn is in use or not. m_write_txn is used as a batch txn, even
@ -3923,13 +3922,20 @@ void BlockchainLMDB::block_rtxn_stop() const
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);
mdb_txn_reset(m_tinfo->m_ti_rtxn); mdb_txn_reset(m_tinfo->m_ti_rtxn);
memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags)); memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags));
/* cancel out the increment from rtxn_start */
mdb_txn_safe::increment_txns(-1);
} }
bool BlockchainLMDB::block_rtxn_start() const bool BlockchainLMDB::block_rtxn_start() const
{ {
MDB_txn *mtxn; MDB_txn *mtxn;
mdb_txn_cursors *mcur; mdb_txn_cursors *mcur;
return block_rtxn_start(&mtxn, &mcur); /* auto_txn is only used for the create gate */
mdb_txn_safe auto_txn;
bool ret = block_rtxn_start(&mtxn, &mcur);
if (ret)
auto_txn.increment_txns(1); /* remember there is an active readtxn */
return ret;
} }
void BlockchainLMDB::block_wtxn_start() void BlockchainLMDB::block_wtxn_start()