Fix a data race between GetColumnFamilyMetaData and MarkFilesBeingCompacted (#6056)
Summary: Use db mutex to protect the execution of Version::GetColumnFamilyMetaData() called in DBImpl::GetColumnFamilyMetaData(). Without mutex, GetColumnFamilyMetaData() races with MarkFilesBeingCompacted() for access to FileMetaData::being_compacted. Other than mutex, there are several more alternatives. - Make FileMetaData::being_compacted an atomic variable. This will make FileMetaData non-copy-able. - Separate being_compacted from FileMetaData. This requires re-organizing data structures that are already used in many places. Test Plan (dev server): ``` make check ``` Pull Request resolved: https://github.com/facebook/rocksdb/pull/6056 Differential Revision: D18620488 Pulled By: riversand963 fbshipit-source-id: 87f89660b5d5e2ab4ef7962b7b2a7d00e346aa3b
This commit is contained in:
parent
c0983d0691
commit
0ce0edbe12
@ -2,6 +2,7 @@
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
* Fix data corruption casued by output of intra-L0 compaction on ingested file not being placed in correct order in L0.
|
* Fix data corruption casued by output of intra-L0 compaction on ingested file not being placed in correct order in L0.
|
||||||
|
* Fix a data race between Version::GetColumnFamilyMetaData() and Compaction::MarkFilesBeingCompacted() for access to being_compacted (#6056). The current fix acquires the db mutex during Version::GetColumnFamilyMetaData(), which may cause regression.
|
||||||
|
|
||||||
### Public API Change
|
### Public API Change
|
||||||
* TTL Compactions in Level compaction style now initiate successive cascading compactions on a key range so that it reaches the bottom level quickly on TTL expiry. `creation_time` table property for compaction output files is now set to the minimum of the creation times of all compaction inputs.
|
* TTL Compactions in Level compaction style now initiate successive cascading compactions on a key range so that it reaches the bottom level quickly on TTL expiry. `creation_time` table property for compaction output files is now set to the minimum of the creation times of all compaction inputs.
|
||||||
|
@ -3241,7 +3241,19 @@ void DBImpl::GetColumnFamilyMetaData(ColumnFamilyHandle* column_family,
|
|||||||
assert(column_family);
|
assert(column_family);
|
||||||
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
|
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
|
||||||
auto* sv = GetAndRefSuperVersion(cfd);
|
auto* sv = GetAndRefSuperVersion(cfd);
|
||||||
sv->current->GetColumnFamilyMetaData(cf_meta);
|
{
|
||||||
|
// Without mutex, Version::GetColumnFamilyMetaData will have data race with
|
||||||
|
// Compaction::MarkFilesBeingCompacted. One solution is to use mutex, but
|
||||||
|
// this may cause regression. An alternative is to make
|
||||||
|
// FileMetaData::being_compacted atomic, but it will make FileMetaData
|
||||||
|
// non-copy-able. Another option is to separate these variables from
|
||||||
|
// original FileMetaData struct, and this requires re-organization of data
|
||||||
|
// structures. For now, we take the easy approach. If
|
||||||
|
// DB::GetColumnFamilyMetaData is not called frequently, the regression
|
||||||
|
// should not be big. We still need to keep an eye on it.
|
||||||
|
InstrumentedMutexLock l(&mutex_);
|
||||||
|
sv->current->GetColumnFamilyMetaData(cf_meta);
|
||||||
|
}
|
||||||
ReturnAndCleanupSuperVersion(cfd, sv);
|
ReturnAndCleanupSuperVersion(cfd, sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user