summaryrefslogtreecommitdiff
path: root/db/db_iterator_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'db/db_iterator_test.cc')
-rw-r--r--db/db_iterator_test.cc113
1 files changed, 113 insertions, 0 deletions
diff --git a/db/db_iterator_test.cc b/db/db_iterator_test.cc
index 7c3bdd850..22fae0c82 100644
--- a/db/db_iterator_test.cc
+++ b/db/db_iterator_test.cc
@@ -3555,6 +3555,119 @@ TEST_F(DBIteratorTest, ErrorWhenReadFile) {
iter->Reset();
}
+TEST_F(DBIteratorTest, IteratorsConsistentViewImplicitSnapshot) {
+ Options options = GetDefaultOptions();
+ CreateAndReopenWithCF({"cf_1", "cf_2"}, options);
+
+ for (int i = 0; i < 3; ++i) {
+ ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
+ "cf" + std::to_string(i) + "_val"));
+ }
+
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
+ {{"DBImpl::BGWorkFlush:done",
+ "DBImpl::MultiCFSnapshot::AfterGetSeqNum1"}});
+
+ bool flushed = false;
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
+ "DBImpl::MultiCFSnapshot::AfterRefSV", [&](void* /*arg*/) {
+ if (!flushed) {
+ for (int i = 0; i < 3; ++i) {
+ ASSERT_OK(Flush(i));
+ ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
+ "cf" + std::to_string(i) + "_val_new"));
+ }
+ flushed = true;
+ }
+ });
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
+ ReadOptions read_options;
+ std::vector<Iterator*> iters;
+ ASSERT_OK(db_->NewIterators(read_options, handles_, &iters));
+
+ for (int i = 0; i < 3; ++i) {
+ auto iter = iters[i];
+ ASSERT_OK(iter->status());
+ iter->SeekToFirst();
+ ASSERT_EQ(IterStatus(iter), "cf" + std::to_string(i) + "_key->cf" +
+ std::to_string(i) + "_val_new");
+ }
+ for (auto* iter : iters) {
+ delete iter;
+ }
+
+ // Thread-local SVs are no longer obsolete nor in use
+ for (int i = 0; i < 3; ++i) {
+ auto* cfd =
+ static_cast_with_check<ColumnFamilyHandleImpl>(handles_[i])->cfd();
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVObsolete);
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
+ }
+}
+
+TEST_F(DBIteratorTest, IteratorsConsistentViewExplicitSnapshot) {
+ Options options = GetDefaultOptions();
+ CreateAndReopenWithCF({"cf_1", "cf_2"}, options);
+
+ for (int i = 0; i < 3; ++i) {
+ ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
+ "cf" + std::to_string(i) + "_val"));
+ }
+
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
+ {{"DBImpl::BGWorkFlush:done",
+ "DBImpl::MultiCFSnapshot::AfterGetSeqNum1"}});
+
+ bool flushed = false;
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
+ "DBImpl::MultiCFSnapshot::AfterRefSV", [&](void* /*arg*/) {
+ if (!flushed) {
+ for (int i = 0; i < 3; ++i) {
+ ASSERT_OK(Flush(i));
+ ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
+ "cf" + std::to_string(i) + "_val_new"));
+ }
+ flushed = true;
+ }
+ });
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
+ // Explicit snapshot wouldn't force reloading all svs. We should expect old
+ // values
+ const Snapshot* snapshot = db_->GetSnapshot();
+ ReadOptions read_options;
+ read_options.snapshot = snapshot;
+ std::vector<Iterator*> iters;
+ ASSERT_OK(db_->NewIterators(read_options, handles_, &iters));
+
+ for (int i = 0; i < 3; ++i) {
+ auto iter = iters[i];
+ ASSERT_OK(iter->status());
+ iter->SeekToFirst();
+ ASSERT_EQ(IterStatus(iter), "cf" + std::to_string(i) + "_key->cf" +
+ std::to_string(i) + "_val");
+ }
+
+ db_->ReleaseSnapshot(snapshot);
+ for (auto* iter : iters) {
+ delete iter;
+ }
+
+ // Thread-local SV for cf_0 is obsolete (flush happened after the first SV
+ // Ref)
+ auto* cfd0 =
+ static_cast_with_check<ColumnFamilyHandleImpl>(handles_[0])->cfd();
+ ASSERT_EQ(cfd0->TEST_GetLocalSV()->Get(), SuperVersion::kSVObsolete);
+ ASSERT_NE(cfd0->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
+
+ // Rest are not InUse nor Obsolete
+ for (int i = 1; i < 3; ++i) {
+ auto* cfd =
+ static_cast_with_check<ColumnFamilyHandleImpl>(handles_[i])->cfd();
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVObsolete);
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
+ }
+}
+
} // namespace ROCKSDB_NAMESPACE
int main(int argc, char** argv) {