Add tests for paranoid checks with range deletion (#7521)
Summary: Added unit tests that have paranoid_check = true that perform range deletions. At the moment, the deleted ranges do not appear to be checked as part of the paranoid checks. Pull Request resolved: https://github.com/facebook/rocksdb/pull/7521 Reviewed By: zhichao-cao Differential Revision: D24262175 Pulled By: ajkr fbshipit-source-id: 1035e968f7ab8ccaa7af086b835a4e72c7e56743
This commit is contained in:
parent
861e544335
commit
bf342394b6
@ -106,7 +106,7 @@ class CorruptionTest : public testing::Test {
|
|||||||
ASSERT_OK(::ROCKSDB_NAMESPACE::RepairDB(dbname_, options_));
|
ASSERT_OK(::ROCKSDB_NAMESPACE::RepairDB(dbname_, options_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Build(int n, int flush_every = 0) {
|
void Build(int n, int start, int flush_every) {
|
||||||
std::string key_space, value_space;
|
std::string key_space, value_space;
|
||||||
WriteBatch batch;
|
WriteBatch batch;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
@ -115,13 +115,15 @@ class CorruptionTest : public testing::Test {
|
|||||||
ASSERT_OK(dbi->TEST_FlushMemTable());
|
ASSERT_OK(dbi->TEST_FlushMemTable());
|
||||||
}
|
}
|
||||||
//if ((i % 100) == 0) fprintf(stderr, "@ %d of %d\n", i, n);
|
//if ((i % 100) == 0) fprintf(stderr, "@ %d of %d\n", i, n);
|
||||||
Slice key = Key(i, &key_space);
|
Slice key = Key(i + start, &key_space);
|
||||||
batch.Clear();
|
batch.Clear();
|
||||||
ASSERT_OK(batch.Put(key, Value(i, &value_space)));
|
ASSERT_OK(batch.Put(key, Value(i + start, &value_space)));
|
||||||
ASSERT_OK(db_->Write(WriteOptions(), &batch));
|
ASSERT_OK(db_->Write(WriteOptions(), &batch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Build(int n, int flush_every = 0) { Build(n, 0, flush_every); }
|
||||||
|
|
||||||
void Check(int min_expected, int max_expected) {
|
void Check(int min_expected, int max_expected) {
|
||||||
uint64_t next_expected = 0;
|
uint64_t next_expected = 0;
|
||||||
uint64_t missed = 0;
|
uint64_t missed = 0;
|
||||||
@ -626,6 +628,105 @@ TEST_F(CorruptionTest, ParanoidFileChecksOnCompact) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeFirst) {
|
||||||
|
Options options;
|
||||||
|
options.check_flush_compaction_key_order = false;
|
||||||
|
options.paranoid_file_checks = true;
|
||||||
|
options.create_if_missing = true;
|
||||||
|
for (bool do_flush : {true, false}) {
|
||||||
|
delete db_;
|
||||||
|
db_ = nullptr;
|
||||||
|
ASSERT_OK(DestroyDB(dbname_, options));
|
||||||
|
ASSERT_OK(DB::Open(options, dbname_, &db_));
|
||||||
|
std::string start, end;
|
||||||
|
assert(db_ != nullptr);
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(3, &start), Key(7, &end)));
|
||||||
|
auto snap = db_->GetSnapshot();
|
||||||
|
ASSERT_NE(snap, nullptr);
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(8, &start), Key(9, &end)));
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(2, &start), Key(5, &end)));
|
||||||
|
Build(10);
|
||||||
|
if (do_flush) {
|
||||||
|
ASSERT_OK(db_->Flush(FlushOptions()));
|
||||||
|
} else {
|
||||||
|
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
|
||||||
|
ASSERT_OK(dbi->TEST_FlushMemTable());
|
||||||
|
ASSERT_OK(dbi->TEST_CompactRange(0, nullptr, nullptr, nullptr, true));
|
||||||
|
}
|
||||||
|
db_->ReleaseSnapshot(snap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRange) {
|
||||||
|
Options options;
|
||||||
|
options.check_flush_compaction_key_order = false;
|
||||||
|
options.paranoid_file_checks = true;
|
||||||
|
options.create_if_missing = true;
|
||||||
|
for (bool do_flush : {true, false}) {
|
||||||
|
delete db_;
|
||||||
|
db_ = nullptr;
|
||||||
|
ASSERT_OK(DestroyDB(dbname_, options));
|
||||||
|
ASSERT_OK(DB::Open(options, dbname_, &db_));
|
||||||
|
assert(db_ != nullptr);
|
||||||
|
Build(10, 0, 0);
|
||||||
|
std::string start, end;
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(5, &start), Key(15, &end)));
|
||||||
|
auto snap = db_->GetSnapshot();
|
||||||
|
ASSERT_NE(snap, nullptr);
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(8, &start), Key(9, &end)));
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(12, &start), Key(17, &end)));
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(2, &start), Key(4, &end)));
|
||||||
|
Build(10, 10, 0);
|
||||||
|
if (do_flush) {
|
||||||
|
ASSERT_OK(db_->Flush(FlushOptions()));
|
||||||
|
} else {
|
||||||
|
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
|
||||||
|
ASSERT_OK(dbi->TEST_FlushMemTable());
|
||||||
|
ASSERT_OK(dbi->TEST_CompactRange(0, nullptr, nullptr, nullptr, true));
|
||||||
|
}
|
||||||
|
db_->ReleaseSnapshot(snap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeLast) {
|
||||||
|
Options options;
|
||||||
|
options.check_flush_compaction_key_order = false;
|
||||||
|
options.paranoid_file_checks = true;
|
||||||
|
options.create_if_missing = true;
|
||||||
|
for (bool do_flush : {true, false}) {
|
||||||
|
delete db_;
|
||||||
|
db_ = nullptr;
|
||||||
|
ASSERT_OK(DestroyDB(dbname_, options));
|
||||||
|
ASSERT_OK(DB::Open(options, dbname_, &db_));
|
||||||
|
assert(db_ != nullptr);
|
||||||
|
std::string start, end;
|
||||||
|
Build(10);
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(3, &start), Key(7, &end)));
|
||||||
|
auto snap = db_->GetSnapshot();
|
||||||
|
ASSERT_NE(snap, nullptr);
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(6, &start), Key(8, &end)));
|
||||||
|
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
|
||||||
|
Key(2, &start), Key(5, &end)));
|
||||||
|
if (do_flush) {
|
||||||
|
ASSERT_OK(db_->Flush(FlushOptions()));
|
||||||
|
} else {
|
||||||
|
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
|
||||||
|
ASSERT_OK(dbi->TEST_FlushMemTable());
|
||||||
|
ASSERT_OK(dbi->TEST_CompactRange(0, nullptr, nullptr, nullptr, true));
|
||||||
|
}
|
||||||
|
db_->ReleaseSnapshot(snap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CorruptionTest, LogCorruptionErrorsInCompactionIterator) {
|
TEST_F(CorruptionTest, LogCorruptionErrorsInCompactionIterator) {
|
||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
|
@ -2932,7 +2932,7 @@ const Snapshot* DBImpl::GetSnapshotForWriteConflictBoundary() {
|
|||||||
SnapshotImpl* DBImpl::GetSnapshotImpl(bool is_write_conflict_boundary,
|
SnapshotImpl* DBImpl::GetSnapshotImpl(bool is_write_conflict_boundary,
|
||||||
bool lock) {
|
bool lock) {
|
||||||
int64_t unix_time = 0;
|
int64_t unix_time = 0;
|
||||||
env_->GetCurrentTime(&unix_time); // Ignore error
|
env_->GetCurrentTime(&unix_time).PermitUncheckedError(); // Ignore error
|
||||||
SnapshotImpl* s = new SnapshotImpl;
|
SnapshotImpl* s = new SnapshotImpl;
|
||||||
|
|
||||||
if (lock) {
|
if (lock) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user