@ -24,6 +24,32 @@
namespace rocksdb {
bool DBImpl : : EnoughRoomForCompaction (
const std : : vector < CompactionInputFiles > & inputs ,
bool * sfm_reserved_compact_space , LogBuffer * log_buffer ) {
// Check if we have enough room to do the compaction
bool enough_room = true ;
# ifndef ROCKSDB_LITE
auto sfm = static_cast < SstFileManagerImpl * > (
immutable_db_options_ . sst_file_manager . get ( ) ) ;
if ( sfm ) {
enough_room = sfm - > EnoughRoomForCompaction ( inputs ) ;
if ( enough_room ) {
* sfm_reserved_compact_space = true ;
}
}
# endif // ROCKSDB_LITE
if ( ! enough_room ) {
// Just in case tests want to change the value of enough_room
TEST_SYNC_POINT_CALLBACK (
" DBImpl::BackgroundCompaction():CancelledCompaction " , & enough_room ) ;
ROCKS_LOG_BUFFER ( log_buffer ,
" Cancelled compaction because not enough room " ) ;
RecordTick ( stats_ , COMPACTION_CANCELLED , 1 ) ;
}
return enough_room ;
}
Status DBImpl : : SyncClosedLogs ( JobContext * job_context ) {
TEST_SYNC_POINT ( " DBImpl::SyncClosedLogs:Start " ) ;
mutex_ . AssertHeld ( ) ;
@ -582,6 +608,16 @@ Status DBImpl::CompactFilesImpl(
" files are already being compacted " ) ;
}
}
bool sfm_reserved_compact_space = false ;
// First check if we have enough room to do the compaction
bool enough_room = EnoughRoomForCompaction (
input_files , & sfm_reserved_compact_space , log_buffer ) ;
if ( ! enough_room ) {
// m's vars will get set properly at the end of this function,
// as long as status == CompactionTooLarge
return Status : : CompactionTooLarge ( ) ;
}
// At this point, CompactFiles will be run.
bg_compaction_scheduled_ + + ;
@ -658,6 +694,14 @@ Status DBImpl::CompactFilesImpl(
* c - > mutable_cf_options ( ) , FlushReason : : kManualCompaction ) ;
}
c - > ReleaseCompactionFiles ( s ) ;
# ifndef ROCKSDB_LITE
// Need to make sure SstFileManager does its bookkeeping
auto sfm = static_cast < SstFileManagerImpl * > (
immutable_db_options_ . sst_file_manager . get ( ) ) ;
if ( sfm & & sfm_reserved_compact_space ) {
sfm - > OnCompactionCompletion ( c . get ( ) ) ;
}
# endif // ROCKSDB_LITE
ReleaseFileNumberFromPendingOutputs ( pending_outputs_inserted_elem ) ;
@ -696,6 +740,7 @@ Status DBImpl::CompactFilesImpl(
if ( bg_compaction_scheduled_ = = 0 ) {
bg_cv_ . SignalAll ( ) ;
}
TEST_SYNC_POINT ( " CompactFilesImpl:End " ) ;
return status ;
}
@ -1578,9 +1623,7 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
// InternalKey manual_end_storage;
// InternalKey* manual_end = &manual_end_storage;
# ifndef ROCKSDB_LITE
bool sfm_bookkeeping = false ;
# endif // ROCKSDB_LITE
bool sfm_reserved_compact_space = false ;
if ( is_manual ) {
ManualCompactionState * m = manual_compaction ;
assert ( m - > in_progress ) ;
@ -1593,6 +1636,18 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
m - > cfd - > GetName ( ) . c_str ( ) , m - > input_level ,
( m - > begin ? m - > begin - > DebugString ( ) . c_str ( ) : " (begin) " ) ,
( m - > end ? m - > end - > DebugString ( ) . c_str ( ) : " (end) " ) ) ;
} else {
// First check if we have enough room to do the compaction
bool enough_room = EnoughRoomForCompaction (
* ( c - > inputs ( ) ) , & sfm_reserved_compact_space , log_buffer ) ;
if ( ! enough_room ) {
// Then don't do the compaction
c - > ReleaseCompactionFiles ( status ) ;
c . reset ( ) ;
// m's vars will get set properly at the end of this function,
// as long as status == CompactionTooLarge
status = Status : : CompactionTooLarge ( ) ;
} else {
ROCKS_LOG_BUFFER (
log_buffer ,
@ -1605,6 +1660,7 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
? " (end) "
: m - > manual_end - > DebugString ( ) . c_str ( ) ) ) ;
}
}
} else if ( ! is_prepicked & & ! compaction_queue_ . empty ( ) ) {
if ( HasExclusiveManualCompaction ( ) ) {
// Can't compact right now, but try again later
@ -1644,24 +1700,10 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
c . reset ( cfd - > PickCompaction ( * mutable_cf_options , log_buffer ) ) ;
TEST_SYNC_POINT ( " DBImpl::BackgroundCompaction():AfterPickCompaction " ) ;
bool enough_room = true ;
if ( c ! = nullptr ) {
# ifndef ROCKSDB_LITE
auto sfm = static_cast < SstFileManagerImpl * > (
immutable_db_options_ . sst_file_manager . get ( ) ) ;
if ( sfm ) {
enough_room = sfm - > EnoughRoomForCompaction ( c . get ( ) ) ;
if ( enough_room ) {
sfm_bookkeeping = true ;
}
}
# endif // ROCKSDB_LITE
if ( ! enough_room ) {
// Just in case tests want to change the value of enough_room
TEST_SYNC_POINT_CALLBACK (
" DBImpl::BackgroundCompaction():CancelledCompaction " ,
& enough_room ) ;
}
bool enough_room = EnoughRoomForCompaction (
* ( c - > inputs ( ) ) , & sfm_reserved_compact_space , log_buffer ) ;
if ( ! enough_room ) {
// Then don't do the compaction
c - > ReleaseCompactionFiles ( status ) ;
@ -1670,9 +1712,6 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
- > storage_info ( )
- > ComputeCompactionScore ( * ( c - > immutable_cf_options ( ) ) ,
* ( c - > mutable_cf_options ( ) ) ) ;
ROCKS_LOG_BUFFER ( log_buffer ,
" Cancelled compaction because not enough room " ) ;
AddToCompactionQueue ( cfd ) ;
+ + unscheduled_compactions_ ;
@ -1680,7 +1719,6 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
// Don't need to sleep here, because BackgroundCallCompaction
// will sleep if !s.ok()
status = Status : : CompactionTooLarge ( ) ;
RecordTick ( stats_ , COMPACTION_CANCELLED , 1 ) ;
} else {
// update statistics
MeasureTime ( stats_ , NUM_FILES_IN_SINGLE_COMPACTION ,
@ -1867,7 +1905,7 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
// Need to make sure SstFileManager does its bookkeeping
auto sfm = static_cast < SstFileManagerImpl * > (
immutable_db_options_ . sst_file_manager . get ( ) ) ;
if ( sfm & & sfm_bookkeeping ) {
if ( sfm & & sfm_reserved_compact_space ) {
sfm - > OnCompactionCompletion ( c . get ( ) ) ;
}
# endif // ROCKSDB_LITE