d_dolog = ::arg().mustDo("query-logging");
}
+LMDBBackend::~LMDBBackend()
+{
+ // LMDB internals require that, if we have multiple transactions active,
+ // we destroy them in the reverse order of their creation, thus we can't
+ // let the default destructor take care of d_rotxn and d_rwtxn.
+ if (d_txnorder) {
+ // RO transaction more recent than RW transaction
+ d_rotxn.reset();
+ d_rwtxn.reset();
+ }
+ else {
+ // RW transaction more recent than RO transaction
+ d_rwtxn.reset();
+ d_rotxn.reset();
+ }
+}
+
namespace boost
{
namespace serialization
throw DBException("Attempt to start a transaction while one was open already");
}
d_rwtxn = getRecordsRWTransaction(real_id);
+ d_txnorder = false;
d_transactiondomain = domain;
d_transactiondomainid = real_id;
}
d_rotxn = getRecordsROTransaction(di.id, d_rwtxn);
+ d_txnorder = true;
d_getcursor = std::make_shared<MDBROCursor>(d_rotxn->txn->getCursor(d_rotxn->db->dbi));
compoundOrdername co;
}
// cout<<"get will look for "<<relqname<< " in zone "<<hunt<<" with id "<<zoneId<<" and type "<<type.toString()<<endl;
d_rotxn = getRecordsROTransaction(zoneId, d_rwtxn);
+ d_txnorder = true;
compoundOrdername co;
d_getcursor = std::make_shared<MDBROCursor>(d_rotxn->txn->getCursor(d_rotxn->db->dbi));
{
public:
explicit LMDBBackend(const string& suffix = "");
+ ~LMDBBackend();
bool list(const DNSName& target, int id, bool include_disabled) override;
shared_ptr<RecordsROTransaction> d_rotxn; // for lookup and list
shared_ptr<RecordsRWTransaction> d_rwtxn; // for feedrecord within begin/aborttransaction
+ bool d_txnorder{false}; // whether d_rotxn is more recent than d_rwtxn
std::shared_ptr<RecordsRWTransaction> getRecordsRWTransaction(uint32_t id);
std::shared_ptr<RecordsROTransaction> getRecordsROTransaction(uint32_t id, const std::shared_ptr<LMDBBackend::RecordsRWTransaction>& rwtxn = nullptr);
int genChangeDomain(const DNSName& domain, const std::function<void(DomainInfo&)>& func);