mirror of https://github.com/facebook/rocksdb.git
Fix sequence number bump logic in multi-CF SST ingestion (#9005)
Summary: The code in `IngestExternalFiles()` that bumps the DB's sequence number depending on what seqnos were assigned to the files has 3 bugs: 1) There is an assertion that the sequence number is increased in all the affected column families, but this is unnecessary, it is fine if some files can stick to a lower sequence number. It is very easy to hit the assertion: it is sufficient to insert 2 files in 2 CFs, one which overlaps the CF and one that doesn't (for example the CF is empty). The line added in the `IngestFilesIntoMultipleColumnFamilies_Success` test makes the assertion fail. 2) SetLastSequence() is called with the sum of all the bumps across CFs, but we should take the maximum instead, as all CFs start with the current seqno and bump it independently. 3) The code above is accidentally under a `#ifndef NDEBUG`, so it doesn't run in optimized builds, so some files may be assigned seqnos from the future. Pull Request resolved: https://github.com/facebook/rocksdb/pull/9005 Test Plan: Added line in `IngestFilesIntoMultipleColumnFamilies_Success` that triggers the assertion, verified that the test (and all the others) pass after the fix. Reviewed By: ajkr Differential Revision: D31597892 Pulled By: ot fbshipit-source-id: c2d3237f90290df1178736ace8653a9623f5a770
This commit is contained in:
parent
b4e59a48fd
commit
4bfd415e34
|
@ -5,6 +5,7 @@
|
||||||
* Fix the incorrect disabling of SST rate limited deletion when the WAL and DB are in different directories. Only WAL rate limited deletion should be disabled if its in a different directory.
|
* Fix the incorrect disabling of SST rate limited deletion when the WAL and DB are in different directories. Only WAL rate limited deletion should be disabled if its in a different directory.
|
||||||
* Fix `DisableManualCompaction()` to cancel compactions even when they are waiting on automatic compactions to drain due to `CompactRangeOptions::exclusive_manual_compactions == true`.
|
* Fix `DisableManualCompaction()` to cancel compactions even when they are waiting on automatic compactions to drain due to `CompactRangeOptions::exclusive_manual_compactions == true`.
|
||||||
* Fix contract of `Env::ReopenWritableFile()` and `FileSystem::ReopenWritableFile()` to specify any existing file must not be deleted or truncated.
|
* Fix contract of `Env::ReopenWritableFile()` and `FileSystem::ReopenWritableFile()` to specify any existing file must not be deleted or truncated.
|
||||||
|
* Fixed bug in calls to `IngestExternalFiles()` with files for multiple column families. The bug could have introduced a delay in ingested file keys becoming visible after `IngestExternalFiles()` returned. Furthermore, mutations to ingested file keys while they were invisible could have been dropped (not necessarily immediately).
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
* Print information about blob files when using "ldb list_live_files_metadata"
|
* Print information about blob files when using "ldb list_live_files_metadata"
|
||||||
|
|
|
@ -4683,14 +4683,11 @@ Status DBImpl::IngestExternalFiles(
|
||||||
if (status.ok()) {
|
if (status.ok()) {
|
||||||
int consumed_seqno_count =
|
int consumed_seqno_count =
|
||||||
ingestion_jobs[0].ConsumedSequenceNumbersCount();
|
ingestion_jobs[0].ConsumedSequenceNumbersCount();
|
||||||
#ifndef NDEBUG
|
|
||||||
for (size_t i = 1; i != num_cfs; ++i) {
|
for (size_t i = 1; i != num_cfs; ++i) {
|
||||||
assert(!!consumed_seqno_count ==
|
consumed_seqno_count =
|
||||||
!!ingestion_jobs[i].ConsumedSequenceNumbersCount());
|
std::max(consumed_seqno_count,
|
||||||
consumed_seqno_count +=
|
ingestion_jobs[i].ConsumedSequenceNumbersCount());
|
||||||
ingestion_jobs[i].ConsumedSequenceNumbersCount();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (consumed_seqno_count > 0) {
|
if (consumed_seqno_count > 0) {
|
||||||
const SequenceNumber last_seqno = versions_->LastSequence();
|
const SequenceNumber last_seqno = versions_->LastSequence();
|
||||||
versions_->SetLastAllocatedSequence(last_seqno + consumed_seqno_count);
|
versions_->SetLastAllocatedSequence(last_seqno + consumed_seqno_count);
|
||||||
|
|
|
@ -141,7 +141,7 @@ class ExternalSstFileIngestionJob {
|
||||||
IngestedFileInfo* file_to_ingest,
|
IngestedFileInfo* file_to_ingest,
|
||||||
SuperVersion* sv);
|
SuperVersion* sv);
|
||||||
|
|
||||||
// Assign `file_to_ingest` the appropriate sequence number and the lowest
|
// Assign `file_to_ingest` the appropriate sequence number and the lowest
|
||||||
// possible level that it can be ingested to according to compaction_style.
|
// possible level that it can be ingested to according to compaction_style.
|
||||||
// REQUIRES: Mutex held
|
// REQUIRES: Mutex held
|
||||||
Status AssignLevelAndSeqnoForIngestedFile(SuperVersion* sv,
|
Status AssignLevelAndSeqnoForIngestedFile(SuperVersion* sv,
|
||||||
|
|
|
@ -2422,6 +2422,12 @@ TEST_P(ExternalSSTFileTest, IngestFilesIntoMultipleColumnFamilies_Success) {
|
||||||
Options options = CurrentOptions();
|
Options options = CurrentOptions();
|
||||||
options.env = fault_injection_env.get();
|
options.env = fault_injection_env.get();
|
||||||
CreateAndReopenWithCF({"pikachu", "eevee"}, options);
|
CreateAndReopenWithCF({"pikachu", "eevee"}, options);
|
||||||
|
|
||||||
|
// Exercise different situations in different column families: two are empty
|
||||||
|
// (so no new sequence number is needed), but at least one overlaps with the
|
||||||
|
// DB and needs to bump the sequence number.
|
||||||
|
ASSERT_OK(db_->Put(WriteOptions(), "foo1", "oldvalue"));
|
||||||
|
|
||||||
std::vector<ColumnFamilyHandle*> column_families;
|
std::vector<ColumnFamilyHandle*> column_families;
|
||||||
column_families.push_back(handles_[0]);
|
column_families.push_back(handles_[0]);
|
||||||
column_families.push_back(handles_[1]);
|
column_families.push_back(handles_[1]);
|
||||||
|
|
Loading…
Reference in New Issue