diff --git a/db_stress_tool/db_stress_test_base.cc b/db_stress_tool/db_stress_test_base.cc index 2ecd3f46ce..dc8a978699 100644 --- a/db_stress_tool/db_stress_test_base.cc +++ b/db_stress_tool/db_stress_test_base.cc @@ -683,7 +683,7 @@ void StressTest::OperateDb(ThreadState* thread) { read_opts.adaptive_readahead = FLAGS_adaptive_readahead; read_opts.readahead_size = FLAGS_readahead_size; if (gflags::GetCommandLineFlagInfoOrDie("ttl").is_default && - FLAGS_skip_expired_data) { + FLAGS_skip_expired_data && FLAGS_ttl < 1) { auto error_msg = IOStatus::InvalidArgument("skip_expired_data must be set with ttl"); } diff --git a/gmock b/gmock new file mode 100644 index 0000000000..e059e9a65a --- /dev/null +++ b/gmock @@ -0,0 +1,4 @@ +Makefile:171: Warning: Compiling in debug mode. Don't use the resulting binary in production +Makefile:171: Warning: Compiling in debug mode. Don't use the resulting binary in production +/usr/bin/ar: creating libspeedb_test_debug.a +/usr/bin/ar: creating libspeedb_debug.a diff --git a/mono_crash.mem.51841.1.blob b/mono_crash.mem.51841.1.blob new file mode 100644 index 0000000000..15dde8e76f Binary files /dev/null and b/mono_crash.mem.51841.1.blob differ diff --git a/utilities/ttl/db_ttl_impl.cc b/utilities/ttl/db_ttl_impl.cc index b1e0ca317c..44b31ae412 100644 --- a/utilities/ttl/db_ttl_impl.cc +++ b/utilities/ttl/db_ttl_impl.cc @@ -442,6 +442,7 @@ Status DBWithTTLImpl::SanityCheckTimestamp(const Slice& str) { } // Checks if the string is stale or not according to TTl provided +// Generic IsStale implementation bool DBWithTTLImpl::IsStale(const Slice& value, int32_t ttl, SystemClock* clock) { if (ttl <= 0) { // Data is fresh if TTL is non-positive @@ -457,13 +458,16 @@ bool DBWithTTLImpl::IsStale(const Slice& value, int32_t ttl, } // IsStale for strict ttl -bool DBWithTTLImpl::IsStale(const Slice& value, - ColumnFamilyHandle* column_family, - const ReadOptions& options) { +bool DBWithTTLImpl::IsStaleStrictTtl(const Slice& value, + ColumnFamilyHandle* column_family, + const ReadOptions& options) { Options opts = GetOptions(column_family); auto filter = std::static_pointer_cast( opts.compaction_filter_factory); int32_t ttl = filter->GetTtl(); + if (ttl <= 0) { + return false; + } if (options.snapshot == nullptr) { SystemClock* clock = (opts.env == nullptr) ? SystemClock::Default().get() @@ -520,7 +524,7 @@ Status DBWithTTLImpl::Get(const ReadOptions& options, return st; } if (options.skip_expired_data) { - if (IsStale(*value, column_family, options)) { + if (IsStaleStrictTtl(*value, column_family, options)) { return Status::NotFound(); } } @@ -540,10 +544,11 @@ std::vector DBWithTTLImpl::MultiGet( if (!statuses[i].ok()) { continue; } + // check if the key has been expired if is_stale == true it's expired + // re-check if the key expired for each key requested by the multiget bool is_stale = false; if (options.skip_expired_data) { - is_stale = false; - if (IsStale((*values)[i], column_family[i], options)) { + if (IsStaleStrictTtl((*values)[i], column_family[i], options)) { statuses[i] = Status::NotFound(); is_stale = true; } diff --git a/utilities/ttl/db_ttl_impl.h b/utilities/ttl/db_ttl_impl.h index ea5123de9c..218ea077b8 100644 --- a/utilities/ttl/db_ttl_impl.h +++ b/utilities/ttl/db_ttl_impl.h @@ -87,8 +87,8 @@ class DBWithTTLImpl : public DBWithTTL { static bool IsStale(const Slice& value, int32_t ttl, SystemClock* clock); // IsStale for strict ttl - bool IsStale(const Slice& value, ColumnFamilyHandle* column_family, - const ReadOptions& options); + bool IsStaleStrictTtl(const Slice& value, ColumnFamilyHandle* column_family, + const ReadOptions& options); static Status AppendTS(const Slice& val, std::string* val_with_ts, SystemClock* clock); diff --git a/utilities/ttl/ttl_test.cc b/utilities/ttl/ttl_test.cc index cbd6bee3ac..81b9e0c343 100644 --- a/utilities/ttl/ttl_test.cc +++ b/utilities/ttl/ttl_test.cc @@ -400,6 +400,7 @@ class TtlTest : public testing::Test { // Choose carefully so that Put, Gets & Compaction complete in 1 second buffer static const int64_t kSampleSize_ = 100; + static const int32_t ttl_ = 1; std::string dbname_; DBWithTTL* db_ttl_; std::unique_ptr env_; @@ -726,8 +727,10 @@ TEST_F(TtlTest, DeleteRangeTest) { CloseTtl(); } -TEST_F(TtlTest, CompactionTTLDoNotAffectSnapTest) { - OpenTtl(1); +// This test is a placeholder and disabled as the current ttl compaction deletes +// kv pair although they are part of a snapshot +TEST_F(TtlTest, DISABLED_CompactionTTLDoNotAffectSnapTest) { + OpenTtl(ttl_); std::string key_1 = "a"; std::string put_value = "val"; auto ropts = ReadOptions(); @@ -735,7 +738,7 @@ TEST_F(TtlTest, CompactionTTLDoNotAffectSnapTest) { ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); ropts.snapshot = db_ttl_->GetSnapshot(); ASSERT_NE(ropts.snapshot, nullptr); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); // TODO prevent from ttl compaction to delete keys referenced by snapshot // ASSERT_OK(db_ttl_->Get(ropts, key_1, &value)); @@ -743,17 +746,18 @@ TEST_F(TtlTest, CompactionTTLDoNotAffectSnapTest) { CloseTtl(); } +// Test if Merge is updating the timestamp after it has been ran TEST_F(TtlTest, CompactionTTLConsiderLatestMergeTest) { Options options; options.create_if_missing = true; options.merge_operator = MergeOperators::CreateStringAppendOperator(); std::string key_1 = "a"; std::string put_value = "1"; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, 1)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); auto ropts = ReadOptions(); std::string value; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->Merge(WriteOptions(), key_1, put_value)); ASSERT_OK(db_ttl_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); ASSERT_OK(db_ttl_->Get(ropts, key_1, &value)); @@ -762,27 +766,34 @@ TEST_F(TtlTest, CompactionTTLConsiderLatestMergeTest) { CloseTtl(); } -TEST_F(TtlTest, CompactionDeleteExpiredKeyTest) { - OpenTtl(1); +// Check that strict ttl is taking into account new updated timestamp by merge +TEST_F(TtlTest, CompactionStrictTTLConsiderLatestMergeTest) { + Options options; + options.create_if_missing = true; + options.merge_operator = MergeOperators::CreateStringAppendOperator(); std::string key_1 = "a"; - std::string key_2 = "b"; - std::string put_value = "val"; + std::string put_value = "1"; + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); + auto ropts = ReadOptions(); + ropts.skip_expired_data = true; std::string value; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); - env_->Sleep(2); - ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); + env_->Sleep(ttl_ + 1); + ASSERT_OK(db_ttl_->Merge(WriteOptions(), key_1, put_value)); ASSERT_OK(db_ttl_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); - ASSERT_TRUE(db_ttl_->Get(ReadOptions(), key_1, &value).IsNotFound()); - // preserve the non expired key - ASSERT_OK(db_ttl_->Get(ReadOptions(), key_2, &value)); + ASSERT_OK(db_ttl_->Get(ropts, key_1, &value)); + ASSERT_TRUE(value.compare(put_value + "," + put_value) == 0); + db_ttl_->ReleaseSnapshot(ropts.snapshot); + CloseTtl(); } +// Test if strict ttl skip expired keys TEST_F(TtlTest, SkipExpiredTtlGetTest) { - OpenTtl(1); + OpenTtl(ttl_); std::string key = "a"; std::string put_value = "val"; ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); auto ropts = ReadOptions(); ropts.skip_expired_data = true; std::string value; @@ -790,15 +801,16 @@ TEST_F(TtlTest, SkipExpiredTtlGetTest) { CloseTtl(); } +// Test if strict ttl skip expired keys accessed by iterators seek to first TEST_F(TtlTest, SkipExpiredTtlIterFirstTest) { - OpenTtl(1); + OpenTtl(ttl_); auto ropts = ReadOptions(); ropts.skip_expired_data = true; std::string key_1 = "a"; std::string key_2 = "b"; std::string put_value = "val"; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); auto itr = db_ttl_->NewIterator(ropts); std::string value; @@ -809,15 +821,16 @@ TEST_F(TtlTest, SkipExpiredTtlIterFirstTest) { CloseTtl(); } +// Test if strict ttl skip expired keys accessed by iterators seek to last TEST_F(TtlTest, SkipExpiredTtlIterLastTest) { - OpenTtl(1); + OpenTtl(ttl_); auto ropts = ReadOptions(); ropts.skip_expired_data = true; std::string key_1 = "a"; std::string key_2 = "b"; std::string put_value = "val"; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); auto itr = db_ttl_->NewIterator(ropts); std::string value; @@ -828,8 +841,9 @@ TEST_F(TtlTest, SkipExpiredTtlIterLastTest) { CloseTtl(); } +// Test if strict ttl skip expired keys accessed by iterators seek next TEST_F(TtlTest, SkipExpiredTtlIterNextTest) { - OpenTtl(1); + OpenTtl(ttl_); std::string key_1 = "a"; std::string key_2 = "b"; std::string key_3 = "c"; @@ -839,7 +853,7 @@ TEST_F(TtlTest, SkipExpiredTtlIterNextTest) { ropts.skip_expired_data = true; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_4, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_3, put_value)); auto itr = db_ttl_->NewIterator(ropts); @@ -853,8 +867,9 @@ TEST_F(TtlTest, SkipExpiredTtlIterNextTest) { CloseTtl(); } +// Test if strict ttl skip expired keys accessed by iterators seek prev TEST_F(TtlTest, SkipExpiredTtlIterPrevTest) { - OpenTtl(1); + OpenTtl(ttl_); std::string key_1 = "a"; std::string key_2 = "b"; std::string key_3 = "c"; @@ -864,7 +879,7 @@ TEST_F(TtlTest, SkipExpiredTtlIterPrevTest) { ropts.skip_expired_data = true; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_4, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_3, put_value)); auto itr = db_ttl_->NewIterator(ropts); @@ -878,8 +893,9 @@ TEST_F(TtlTest, SkipExpiredTtlIterPrevTest) { CloseTtl(); } +// Test if strict ttl skip expired keys accessed by iterators seek TEST_F(TtlTest, SkipExpiredTtlIterSeekTest) { - OpenTtl(1); + OpenTtl(ttl_); std::string key_1 = "a"; std::string key_2 = "b"; std::string key_3 = "c"; @@ -889,7 +905,7 @@ TEST_F(TtlTest, SkipExpiredTtlIterSeekTest) { ropts.skip_expired_data = true; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_4, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_3, put_value)); auto itr = db_ttl_->NewIterator(ropts); @@ -901,8 +917,9 @@ TEST_F(TtlTest, SkipExpiredTtlIterSeekTest) { CloseTtl(); } +// Test if strict ttl skip expired keys accessed by iterators seek prev TEST_F(TtlTest, SkipExpiredTtlIterSeekPrevTest) { - OpenTtl(1); + OpenTtl(ttl_); auto ropts = ReadOptions(); ropts.skip_expired_data = true; std::string key_1 = "a"; @@ -912,7 +929,7 @@ TEST_F(TtlTest, SkipExpiredTtlIterSeekPrevTest) { std::string put_value = "val"; ASSERT_OK(db_ttl_->Put(WriteOptions(), key_4, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); - env_->Sleep(2); + env_->Sleep(ttl_ + 1); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_3, put_value)); auto itr = db_ttl_->NewIterator(ropts); @@ -924,6 +941,7 @@ TEST_F(TtlTest, SkipExpiredTtlIterSeekPrevTest) { CloseTtl(); } +// Test if strict ttl skip expired keys when multiget is being used TEST_F(TtlTest, SkipExpiredTtlGetMultiTest) { OpenTtl(1); std::string key = "a"; @@ -937,12 +955,13 @@ TEST_F(TtlTest, SkipExpiredTtlGetMultiTest) { CloseTtl(); } +// Test if strict ttl returns non expired items TEST_F(TtlTest, GetNotExpiredTtlGetTest) { - OpenTtl(100); + OpenTtl(ttl_ + 1); std::string key = "a"; std::string put_value = "val"; ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); - env_->Sleep(1); + env_->Sleep(ttl_); auto ropts = ReadOptions(); ropts.skip_expired_data = true; std::string value; @@ -950,6 +969,7 @@ TEST_F(TtlTest, GetNotExpiredTtlGetTest) { CloseTtl(); } +// Test if strict ttl skip expired as read only TEST_F(TtlTest, SkipExpiredReadOnlyTtlMultiGetTest) { Options options; options.create_if_missing = true; @@ -960,13 +980,12 @@ TEST_F(TtlTest, SkipExpiredReadOnlyTtlMultiGetTest) { std::string key_2 = "b"; std::string put_value = "val"; std::vector values; - int ttl = 2; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_1, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key_2, put_value)); db_ttl_->Close(); - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl, true)); - env_->Sleep(ttl + 1); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_, true)); + env_->Sleep(ttl_ + 1); auto statuses = db_ttl_->MultiGet(ropts, {key_1, key_2}, &values); for (auto& status : statuses) { ASSERT_TRUE(status.IsNotFound()); @@ -974,6 +993,7 @@ TEST_F(TtlTest, SkipExpiredReadOnlyTtlMultiGetTest) { CloseTtl(); } +// Test if strict ttl does not skip unexpired as read only TEST_F(TtlTest, GetNotExpiredReadOnlyTtlGetTest) { Options options; options.create_if_missing = true; @@ -983,17 +1003,18 @@ TEST_F(TtlTest, GetNotExpiredReadOnlyTtlGetTest) { std::string value; std::string key = "a"; std::string put_value = "val"; - int ttl = 2; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); db_ttl_->Close(); // open ttl as read only - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl, true)); - env_->Sleep(ttl + 1); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_, true)); + env_->Sleep(ttl_ + 1); ASSERT_TRUE(db_ttl_->Get(ropts, key, &value).IsNotFound()); CloseTtl(); } +// Test if the expiration time is based on snapshot creation and not the current +// time (should not skip here) TEST_F(TtlTest, GetFromSnapshotTtlGetTest) { Options options; options.create_if_missing = true; @@ -1015,6 +1036,8 @@ TEST_F(TtlTest, GetFromSnapshotTtlGetTest) { CloseTtl(); } +// Test if the expiration time is based on snapshot creation and not the current +// time (should skip here) TEST_F(TtlTest, ExpireSnapshotTtlGetTest) { Options options; options.create_if_missing = true; @@ -1025,10 +1048,9 @@ TEST_F(TtlTest, ExpireSnapshotTtlGetTest) { std::string key = "a"; std::string put_value = "val"; const Snapshot* snap; - int ttl = 2; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); - env_->Sleep(ttl + 1); + env_->Sleep(ttl_ + 1); snap = db_ttl_->GetSnapshot(); ropts.snapshot = snap; ASSERT_TRUE(db_ttl_->Get(ropts, "a", &value).IsNotFound()); @@ -1036,6 +1058,8 @@ TEST_F(TtlTest, ExpireSnapshotTtlGetTest) { CloseTtl(); } +// Test if the expiration time is based on iterator creation and not the current +// time (should not skip here) TEST_F(TtlTest, GetFromIteratorTtlGetTest) { Options options; options.create_if_missing = true; @@ -1046,11 +1070,10 @@ TEST_F(TtlTest, GetFromIteratorTtlGetTest) { std::string put_value = "val"; std::string value; Iterator* iter; - int ttl = 2; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); iter = db_ttl_->NewIterator(ropts); - env_->Sleep(ttl + 1); + env_->Sleep(ttl_ + 1); ASSERT_NE(iter, nullptr); iter->Seek(key); ASSERT_TRUE(iter->Valid()); @@ -1059,6 +1082,8 @@ TEST_F(TtlTest, GetFromIteratorTtlGetTest) { CloseTtl(); } +// Test if the expiration time is based on iterator creation and not the current +// time (should skip here) TEST_F(TtlTest, ExpireIteratorTtlGetTest) { Options options; options.create_if_missing = true; @@ -1069,10 +1094,9 @@ TEST_F(TtlTest, ExpireIteratorTtlGetTest) { Iterator* iter; std::string key = "a"; std::string put_value = "val"; - int ttl = 2; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); - env_->Sleep(ttl + 1); + env_->Sleep(ttl_ + 1); iter = db_ttl_->NewIterator(ropts); iter->Seek(key); ASSERT_FALSE(iter->Valid()); @@ -1080,6 +1104,8 @@ TEST_F(TtlTest, ExpireIteratorTtlGetTest) { CloseTtl(); } +// Test if the expiration time is based on snapshot creation and not the +// iterator creation (should not skip here) TEST_F(TtlTest, GetFromSnapshotIteratorTtlGetTest) { Options options; options.create_if_missing = true; @@ -1091,12 +1117,11 @@ TEST_F(TtlTest, GetFromSnapshotIteratorTtlGetTest) { std::string key = "a"; std::string put_value = "val"; Iterator* iter; - int ttl = 2; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); snap = db_ttl_->GetSnapshot(); ropts.snapshot = snap; - env_->Sleep(ttl + 1); + env_->Sleep(ttl_ + 1); iter = db_ttl_->NewIterator(ropts); iter->Seek(key); ASSERT_TRUE(iter->Valid()); @@ -1106,6 +1131,8 @@ TEST_F(TtlTest, GetFromSnapshotIteratorTtlGetTest) { CloseTtl(); } +// Test if the expiration time is based on snapshot creation and not the +// iterator creation (should skip here) TEST_F(TtlTest, ExpireIteratorFromSnapshotTtlGetTest) { Options options; options.create_if_missing = true; @@ -1117,10 +1144,9 @@ TEST_F(TtlTest, ExpireIteratorFromSnapshotTtlGetTest) { std::string key = "a"; std::string put_value = "val"; Iterator* iter; - int ttl = 2; - ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl)); + ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_, ttl_)); ASSERT_OK(db_ttl_->Put(WriteOptions(), key, put_value)); - env_->Sleep(ttl + 1); + env_->Sleep(ttl_ + 1); snap = db_ttl_->GetSnapshot(); ropts.snapshot = snap; iter = db_ttl_->NewIterator(ropts); @@ -1131,6 +1157,7 @@ TEST_F(TtlTest, ExpireIteratorFromSnapshotTtlGetTest) { CloseTtl(); } +// Test strict ttl with multiple CFs TEST_F(TtlTest, SkipExpiredColumnFamiliesTest) { Options options; options.create_if_missing = true; @@ -1141,19 +1168,18 @@ TEST_F(TtlTest, SkipExpiredColumnFamiliesTest) { std::string put_value = "val"; std::string value; std::vector handles; - int ttl = 2; ASSERT_OK(DBWithTTL::Open(options, dbname_, &db_ttl_)); ColumnFamilyHandle* first_handle; ColumnFamilyHandle* second_handle; ASSERT_OK(db_ttl_->CreateColumnFamilyWithTtl(options, "ttl_column_family_1", - &first_handle, ttl)); + &first_handle, ttl_)); handles.push_back(first_handle); ASSERT_OK(db_ttl_->CreateColumnFamilyWithTtl(options, "ttl_column_family_2", &second_handle, 0)); handles.push_back(second_handle); ASSERT_OK(db_ttl_->Put(WriteOptions(), handles[0], key, put_value)); ASSERT_OK(db_ttl_->Put(WriteOptions(), handles[1], key, put_value)); - env_->Sleep(ttl + 1); + env_->Sleep(ttl_ + 1); ASSERT_TRUE(db_ttl_->Get(ropts, handles[0], key, &value).IsNotFound()); ASSERT_OK(db_ttl_->Get(ropts, handles[1], key, &value)); for (auto& h : handles) {