Fix the issue where compaction incorrectly drops a key when there is a snapshot with a sequence number of zero. (#13155)

Summary:
The compaction will incorrectly drop a key under the following conditions:

1. Open an empty database.
2. Use the `IngestExternalFile` API to ingest an SST file (the global sequence number will be 0).
3. Create a snapshot (the snapshot sequence number will be 0).
4. Trigger compaction; the key in the above SST file will be dropped.

The drop condition is found here: f20d12adc8/db/compaction/compaction_iterator.cc (L875-L878)
The condition does not explicitly check if a previous key exists.

Fix: Add a check of `last_sequence != kMaxSequenceNumber` to verify if there is a previous key

Pull Request resolved: https://github.com/facebook/rocksdb/pull/13155

Reviewed By: jowlyzhang

Differential Revision: D66473015

Pulled By: cbi42

fbshipit-source-id: 93a3ec5c103f95e9bb97e3944ba6e752a5394421
This commit is contained in:
tcwzxx 2024-12-02 13:31:19 -08:00 committed by Facebook GitHub Bot
parent 346055a9ea
commit 4ed79f5bd1
3 changed files with 27 additions and 2 deletions

View file

@ -872,8 +872,8 @@ void CompactionIterator::NextFromInput() {
if (Valid()) {
at_next_ = true;
}
} else if (last_snapshot == current_user_key_snapshot_ ||
(last_snapshot > 0 &&
} else if (last_sequence != kMaxSequenceNumber &&
(last_snapshot == current_user_key_snapshot_ ||
last_snapshot < current_user_key_snapshot_)) {
// If the earliest snapshot is which this key is visible in
// is the same as the visibility of a previous instance of the

View file

@ -833,6 +833,14 @@ TEST_P(CompactionIteratorTest, ConvertToPutAtBottom) {
true /*bottomost_level*/);
}
TEST_P(CompactionIteratorTest, ZeroSeqOfKeyAndSnapshot) {
AddSnapshot(0);
const std::vector<std::string> input_keys = {
test::KeyStr("a", 0, kTypeValue), test::KeyStr("b", 0, kTypeValue)};
const std::vector<std::string> input_values = {"a1", "b1"};
RunTest(input_keys, input_values, input_keys, input_values);
}
INSTANTIATE_TEST_CASE_P(CompactionIteratorTestInstance, CompactionIteratorTest,
testing::Values(true, false));
@ -1846,6 +1854,22 @@ TEST_P(CompactionIteratorTsGcTest, SingleDeleteAllKeysOlderThanThreshold) {
}
}
TEST_P(CompactionIteratorTsGcTest, ZeroSeqOfKeyAndSnapshot) {
AddSnapshot(0);
std::string full_history_ts_low;
PutFixed64(&full_history_ts_low, std::numeric_limits<uint64_t>::max());
const std::vector<std::string> input_keys = {
test::KeyStr(101, "a", 0, kTypeValue),
test::KeyStr(102, "b", 0, kTypeValue)};
const std::vector<std::string> input_values = {"a1", "b1"};
RunTest(input_keys, input_values, input_keys, input_values,
/*last_committed_seq=*/kMaxSequenceNumber,
/*merge_operator=*/nullptr, /*compaction_filter=*/nullptr,
/*bottommost_level=*/false,
/*earliest_write_conflict_snapshot=*/kMaxSequenceNumber,
/*key_not_exists_beyond_output_level=*/false, &full_history_ts_low);
}
INSTANTIATE_TEST_CASE_P(CompactionIteratorTsGcTestInstance,
CompactionIteratorTsGcTest,
testing::Values(true, false));

View file

@ -0,0 +1 @@
Fix the issue where compaction incorrectly drops a key when there is a snapshot with a sequence number of zero.