diff --git a/tools/db_stress.cc b/tools/db_stress.cc index 2df610104..63d18efae 100644 --- a/tools/db_stress.cc +++ b/tools/db_stress.cc @@ -1930,6 +1930,9 @@ class StressTest { i == thread->snapshot_queue.front().first) { auto snap_state = thread->snapshot_queue.front().second; assert(snap_state.snapshot); + // Note: this is unsafe as the cf might be dropped concurrently. But it + // is ok since unclean cf drop is cunnrently not supported by write + // prepared transactions. Status s = AssertSame(db_, column_families_[snap_state.cf_at], snap_state); if (!s.ok()) { @@ -2589,6 +2592,23 @@ class StressTest { s = TransactionDB::Open(options_, txn_db_options, FLAGS_db, cf_descriptors, &column_families_, &txn_db_); db_ = txn_db_; + // after a crash, rollback to commit recovered transactions + std::vector trans; + txn_db_->GetAllPreparedTransactions(&trans); + Random rand(FLAGS_seed); + for (auto txn : trans) { + if (rand.OneIn(2)) { + s = txn->Commit(); + assert(s.ok()); + } else { + s = txn->Rollback(); + assert(s.ok()); + } + delete txn; + } + trans.clear(); + txn_db_->GetAllPreparedTransactions(&trans); + assert(trans.size() == 0); #endif } assert(!s.ok() || column_families_.size() == diff --git a/util/duplicate_detector.h b/util/duplicate_detector.h index 46549a98d..5879a5240 100644 --- a/util/duplicate_detector.h +++ b/util/duplicate_detector.h @@ -5,6 +5,12 @@ #pragma once +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#include + #include "util/set_comparator.h" namespace rocksdb { @@ -41,7 +47,25 @@ class DuplicateDetector { using CFKeys = std::set; std::map keys_; void InitWithComp(const uint32_t cf) { - auto cmp = db_->GetColumnFamilyHandle(cf)->GetComparator(); + auto h = db_->GetColumnFamilyHandle(cf); + if (!h) { + // TODO(myabandeh): This is not a concern in MyRocks as drop cf is not + // implemented yet. When it does, we should return proper error instead + // of throwing exception. + ROCKS_LOG_FATAL( + db_->immutable_db_options().info_log, + "Recovering an entry from the dropped column family %" PRIu32 + ". WAL must must have been emptied before dropping the column " + "family"); +#ifndef ROCKSDB_LITE + throw std::runtime_error( + "Recovering an entry from the dropped column family %" PRIu32 + ". WAL must must have been flushed before dropping the column " + "family"); +#endif + return; + } + auto cmp = h->GetComparator(); keys_[cf] = CFKeys(SetComparator(cmp)); } };