@ -1763,6 +1763,7 @@ Status DBImpl::RunManualCompaction(
CompactionArg * ca = nullptr ;
CompactionArg * ca = nullptr ;
bool scheduled = false ;
bool scheduled = false ;
Env : : Priority thread_pool_priority = Env : : Priority : : TOTAL ;
bool manual_conflict = false ;
bool manual_conflict = false ;
ManualCompactionState manual ;
ManualCompactionState manual ;
manual . cfd = cfd ;
manual . cfd = cfd ;
@ -1884,9 +1885,9 @@ Status DBImpl::RunManualCompaction(
manual . done = true ;
manual . done = true ;
manual . status =
manual . status =
Status : : Incomplete ( Status : : SubCode : : kManualCompactionPaused ) ;
Status : : Incomplete ( Status : : SubCode : : kManualCompactionPaused ) ;
if ( ca & & ca - > prepicked_compaction ) {
assert ( thread_pool_priority ! = Env : : Priority : : TOTAL ) ;
ca - > prepicked_compaction - > is_canceled = true ;
env_ - > UnSchedule ( GetTaskTag ( TaskType : : kManualCompaction ) ,
}
thread_pool_priority ) ;
break ;
break ;
}
}
if ( scheduled & & manual . incomplete = = true ) {
if ( scheduled & & manual . incomplete = = true ) {
@ -1916,13 +1917,17 @@ Status DBImpl::RunManualCompaction(
bg_bottom_compaction_scheduled_ + + ;
bg_bottom_compaction_scheduled_ + + ;
ca - > compaction_pri_ = Env : : Priority : : BOTTOM ;
ca - > compaction_pri_ = Env : : Priority : : BOTTOM ;
env_ - > Schedule ( & DBImpl : : BGWorkBottomCompaction , ca ,
env_ - > Schedule ( & DBImpl : : BGWorkBottomCompaction , ca ,
Env : : Priority : : BOTTOM , this ,
Env : : Priority : : BOTTOM ,
GetTaskTag ( TaskType : : kManualCompaction ) ,
& DBImpl : : UnscheduleCompactionCallback ) ;
& DBImpl : : UnscheduleCompactionCallback ) ;
thread_pool_priority = Env : : Priority : : BOTTOM ;
} else {
} else {
bg_compaction_scheduled_ + + ;
bg_compaction_scheduled_ + + ;
ca - > compaction_pri_ = Env : : Priority : : LOW ;
ca - > compaction_pri_ = Env : : Priority : : LOW ;
env_ - > Schedule ( & DBImpl : : BGWorkCompaction , ca , Env : : Priority : : LOW , this ,
env_ - > Schedule ( & DBImpl : : BGWorkCompaction , ca , Env : : Priority : : LOW ,
GetTaskTag ( TaskType : : kManualCompaction ) ,
& DBImpl : : UnscheduleCompactionCallback ) ;
& DBImpl : : UnscheduleCompactionCallback ) ;
thread_pool_priority = Env : : Priority : : LOW ;
}
}
scheduled = true ;
scheduled = true ;
TEST_SYNC_POINT ( " DBImpl::RunManualCompaction:Scheduled " ) ;
TEST_SYNC_POINT ( " DBImpl::RunManualCompaction:Scheduled " ) ;
@ -1933,6 +1938,13 @@ Status DBImpl::RunManualCompaction(
assert ( ! manual . in_progress ) ;
assert ( ! manual . in_progress ) ;
assert ( HasPendingManualCompaction ( ) ) ;
assert ( HasPendingManualCompaction ( ) ) ;
RemoveManualCompaction ( & manual ) ;
RemoveManualCompaction ( & manual ) ;
// if the manual job is unscheduled, try schedule other jobs in case there's
// any unscheduled compaction job which was blocked by exclusive manual
// compaction.
if ( manual . status . IsIncomplete ( ) & &
manual . status . subcode ( ) = = Status : : SubCode : : kManualCompactionPaused ) {
MaybeScheduleFlushOrCompaction ( ) ;
}
bg_cv_ . SignalAll ( ) ;
bg_cv_ . SignalAll ( ) ;
return manual . status ;
return manual . status ;
}
}
@ -2661,6 +2673,8 @@ void DBImpl::UnscheduleCompactionCallback(void* arg) {
delete reinterpret_cast < CompactionArg * > ( arg ) ;
delete reinterpret_cast < CompactionArg * > ( arg ) ;
if ( ca . prepicked_compaction ! = nullptr ) {
if ( ca . prepicked_compaction ! = nullptr ) {
if ( ca . prepicked_compaction - > compaction ! = nullptr ) {
if ( ca . prepicked_compaction - > compaction ! = nullptr ) {
ca . prepicked_compaction - > compaction - > ReleaseCompactionFiles (
Status : : Incomplete ( Status : : SubCode : : kManualCompactionPaused ) ) ;
delete ca . prepicked_compaction - > compaction ;
delete ca . prepicked_compaction - > compaction ;
}
}
delete ca . prepicked_compaction ;
delete ca . prepicked_compaction ;
@ -2851,106 +2865,93 @@ void DBImpl::BackgroundCallFlush(Env::Priority thread_pri) {
void DBImpl : : BackgroundCallCompaction ( PrepickedCompaction * prepicked_compaction ,
void DBImpl : : BackgroundCallCompaction ( PrepickedCompaction * prepicked_compaction ,
Env : : Priority bg_thread_pri ) {
Env : : Priority bg_thread_pri ) {
bool made_progress = false ;
bool made_progress = false ;
JobContext job_context ( next_job_id_ . fetch_add ( 1 ) , true ) ;
TEST_SYNC_POINT ( " BackgroundCallCompaction:0 " ) ;
TEST_SYNC_POINT ( " BackgroundCallCompaction:0 " ) ;
LogBuffer log_buffer ( InfoLogLevel : : INFO_LEVEL ,
LogBuffer log_buffer ( InfoLogLevel : : INFO_LEVEL ,
immutable_db_options_ . info_log . get ( ) ) ;
immutable_db_options_ . info_log . get ( ) ) ;
{
{
InstrumentedMutexLock l ( & mutex_ ) ;
InstrumentedMutexLock l ( & mutex_ ) ;
if ( prepicked_compaction & & prepicked_compaction - > is_canceled ) {
// This call will unlock/lock the mutex to wait for current running
assert ( prepicked_compaction - > compaction ) ;
// IngestExternalFile() calls to finish.
ROCKS_LOG_BUFFER ( & log_buffer , " [%s] Skip canceled manual compaction job " ,
WaitForIngestFile ( ) ;
prepicked_compaction - > compaction - > column_family_data ( )
- > GetName ( )
num_running_compactions_ + + ;
. c_str ( ) ) ;
prepicked_compaction - > compaction - > ReleaseCompactionFiles (
std : : unique_ptr < std : : list < uint64_t > : : iterator >
Status : : Incomplete ( Status : : SubCode : : kManualCompactionPaused ) ) ;
pending_outputs_inserted_elem ( new std : : list < uint64_t > : : iterator (
delete prepicked_compaction - > compaction ;
CaptureCurrentFileNumberInPendingOutputs ( ) ) ) ;
} else {
JobContext job_context ( next_job_id_ . fetch_add ( 1 ) , true ) ;
assert ( ( bg_thread_pri = = Env : : Priority : : BOTTOM & &
// This call will unlock/lock the mutex to wait for current running
bg_bottom_compaction_scheduled_ ) | |
// IngestExternalFile() calls to finish.
( bg_thread_pri = = Env : : Priority : : LOW & & bg_compaction_scheduled_ ) ) ;
WaitForIngestFile ( ) ;
Status s = BackgroundCompaction ( & made_progress , & job_context , & log_buffer ,
prepicked_compaction , bg_thread_pri ) ;
num_running_compactions_ + + ;
TEST_SYNC_POINT ( " BackgroundCallCompaction:1 " ) ;
if ( s . IsBusy ( ) ) {
std : : unique_ptr < std : : list < uint64_t > : : iterator >
bg_cv_ . SignalAll ( ) ; // In case a waiter can proceed despite the error
pending_outputs_inserted_elem ( new std : : list < uint64_t > : : iterator (
mutex_ . Unlock ( ) ;
CaptureCurrentFileNumberInPendingOutputs ( ) ) ) ;
immutable_db_options_ . clock - > SleepForMicroseconds (
10000 ) ; // prevent hot loop
assert ( ( bg_thread_pri = = Env : : Priority : : BOTTOM & &
mutex_ . Lock ( ) ;
bg_bottom_compaction_scheduled_ ) | |
} else if ( ! s . ok ( ) & & ! s . IsShutdownInProgress ( ) & &
( bg_thread_pri = = Env : : Priority : : LOW & & bg_compaction_scheduled_ ) ) ;
! s . IsManualCompactionPaused ( ) & & ! s . IsColumnFamilyDropped ( ) ) {
Status s = BackgroundCompaction ( & made_progress , & job_context , & log_buffer ,
// Wait a little bit before retrying background compaction in
prepicked_compaction , bg_thread_pri ) ;
// case this is an environmental problem and we do not want to
TEST_SYNC_POINT ( " BackgroundCallCompaction:1 " ) ;
// chew up resources for failed compactions for the duration of
if ( s . IsBusy ( ) ) {
// the problem.
bg_cv_ . SignalAll ( ) ; // In case a waiter can proceed despite the error
uint64_t error_cnt =
mutex_ . Unlock ( ) ;
default_cf_internal_stats_ - > BumpAndGetBackgroundErrorCount ( ) ;
immutable_db_options_ . clock - > SleepForMicroseconds (
bg_cv_ . SignalAll ( ) ; // In case a waiter can proceed despite the error
10000 ) ; // prevent hot loop
mutex_ . Unlock ( ) ;
mutex_ . Lock ( ) ;
log_buffer . FlushBufferToLog ( ) ;
} else if ( ! s . ok ( ) & & ! s . IsShutdownInProgress ( ) & &
ROCKS_LOG_ERROR ( immutable_db_options_ . info_log ,
! s . IsManualCompactionPaused ( ) & & ! s . IsColumnFamilyDropped ( ) ) {
" Waiting after background compaction error: %s, "
// Wait a little bit before retrying background compaction in
" Accumulated background error counts: % " PRIu64 ,
// case this is an environmental problem and we do not want to
s . ToString ( ) . c_str ( ) , error_cnt ) ;
// chew up resources for failed compactions for the duration of
LogFlush ( immutable_db_options_ . info_log ) ;
// the problem.
immutable_db_options_ . clock - > SleepForMicroseconds ( 1000000 ) ;
uint64_t error_cnt =
mutex_ . Lock ( ) ;
default_cf_internal_stats_ - > BumpAndGetBackgroundErrorCount ( ) ;
} else if ( s . IsManualCompactionPaused ( ) ) {
bg_cv_ . SignalAll ( ) ; // In case a waiter can proceed despite the error
assert ( prepicked_compaction ) ;
mutex_ . Unlock ( ) ;
ManualCompactionState * m = prepicked_compaction - > manual_compaction_state ;
log_buffer . FlushBufferToLog ( ) ;
assert ( m ) ;
ROCKS_LOG_ERROR ( immutable_db_options_ . info_log ,
ROCKS_LOG_BUFFER ( & log_buffer , " [%s] [JOB %d] Manual compaction paused " ,
" Waiting after background compaction error: %s, "
m - > cfd - > GetName ( ) . c_str ( ) , job_context . job_id ) ;
" Accumulated background error counts: % " PRIu64 ,
}
s . ToString ( ) . c_str ( ) , error_cnt ) ;
LogFlush ( immutable_db_options_ . info_log ) ;
ReleaseFileNumberFromPendingOutputs ( pending_outputs_inserted_elem ) ;
immutable_db_options_ . clock - > SleepForMicroseconds ( 1000000 ) ;
mutex_ . Lock ( ) ;
} else if ( s . IsManualCompactionPaused ( ) ) {
assert ( prepicked_compaction ) ;
ManualCompactionState * m =
prepicked_compaction - > manual_compaction_state ;
assert ( m ) ;
ROCKS_LOG_BUFFER ( & log_buffer , " [%s] [JOB %d] Manual compaction paused " ,
m - > cfd - > GetName ( ) . c_str ( ) , job_context . job_id ) ;
}
ReleaseFileNumberFromPendingOutputs ( pending_outputs_inserted_elem ) ;
// If compaction failed, we want to delete all temporary files that we
// might have created (they might not be all recorded in job_context in
// case of a failure). Thus, we force full scan in FindObsoleteFiles()
FindObsoleteFiles ( & job_context , ! s . ok ( ) & & ! s . IsShutdownInProgress ( ) & &
! s . IsManualCompactionPaused ( ) & &
! s . IsColumnFamilyDropped ( ) & &
! s . IsBusy ( ) ) ;
TEST_SYNC_POINT ( " DBImpl::BackgroundCallCompaction:FoundObsoleteFiles " ) ;
// delete unnecessary files if any, this is done outside the mutex
if ( job_context . HaveSomethingToClean ( ) | |
job_context . HaveSomethingToDelete ( ) | | ! log_buffer . IsEmpty ( ) ) {
mutex_ . Unlock ( ) ;
// Have to flush the info logs before bg_compaction_scheduled_--
// because if bg_flush_scheduled_ becomes 0 and the lock is
// released, the deconstructor of DB can kick in and destroy all the
// states of DB so info_log might not be available after that point.
// It also applies to access other states that DB owns.
log_buffer . FlushBufferToLog ( ) ;
if ( job_context . HaveSomethingToDelete ( ) ) {
PurgeObsoleteFiles ( job_context ) ;
TEST_SYNC_POINT (
" DBImpl::BackgroundCallCompaction:PurgedObsoleteFiles " ) ;
}
job_context . Clean ( ) ;
mutex_ . Lock ( ) ;
}
assert ( num_running_compactions_ > 0 ) ;
// If compaction failed, we want to delete all temporary files that we
num_running_compactions_ - - ;
// might have created (they might not be all recorded in job_context in
// case of a failure). Thus, we force full scan in FindObsoleteFiles()
FindObsoleteFiles ( & job_context , ! s . ok ( ) & & ! s . IsShutdownInProgress ( ) & &
! s . IsManualCompactionPaused ( ) & &
! s . IsColumnFamilyDropped ( ) & &
! s . IsBusy ( ) ) ;
TEST_SYNC_POINT ( " DBImpl::BackgroundCallCompaction:FoundObsoleteFiles " ) ;
// delete unnecessary files if any, this is done outside the mutex
if ( job_context . HaveSomethingToClean ( ) | |
job_context . HaveSomethingToDelete ( ) | | ! log_buffer . IsEmpty ( ) ) {
mutex_ . Unlock ( ) ;
// Have to flush the info logs before bg_compaction_scheduled_--
// because if bg_flush_scheduled_ becomes 0 and the lock is
// released, the deconstructor of DB can kick in and destroy all the
// states of DB so info_log might not be available after that point.
// It also applies to access other states that DB owns.
log_buffer . FlushBufferToLog ( ) ;
if ( job_context . HaveSomethingToDelete ( ) ) {
PurgeObsoleteFiles ( job_context ) ;
TEST_SYNC_POINT ( " DBImpl::BackgroundCallCompaction:PurgedObsoleteFiles " ) ;
}
job_context . Clean ( ) ;
mutex_ . Lock ( ) ;
}
}
assert ( num_running_compactions_ > 0 ) ;
num_running_compactions_ - - ;
if ( bg_thread_pri = = Env : : Priority : : LOW ) {
if ( bg_thread_pri = = Env : : Priority : : LOW ) {
bg_compaction_scheduled_ - - ;
bg_compaction_scheduled_ - - ;
} else {
} else {