@ -871,7 +871,7 @@ Status DBImpl::TablesRangeTombstoneSummary(ColumnFamilyHandle* column_family,
column_family ) ;
column_family ) ;
ColumnFamilyData * cfd = cfh - > cfd ( ) ;
ColumnFamilyData * cfd = cfh - > cfd ( ) ;
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( this ) ;
Version * version = super_version - > current ;
Version * version = super_version - > current ;
Status s =
Status s =
@ -887,7 +887,6 @@ void DBImpl::ScheduleBgLogWriterClose(JobContext* job_context) {
AddToLogsToFreeQueue ( l ) ;
AddToLogsToFreeQueue ( l ) ;
}
}
job_context - > logs_to_free . clear ( ) ;
job_context - > logs_to_free . clear ( ) ;
SchedulePurge ( ) ;
}
}
}
}
@ -1314,6 +1313,14 @@ void DBImpl::BackgroundCallPurge() {
delete log_writer ;
delete log_writer ;
mutex_ . Lock ( ) ;
mutex_ . Lock ( ) ;
}
}
while ( ! superversions_to_free_queue_ . empty ( ) ) {
assert ( ! superversions_to_free_queue_ . empty ( ) ) ;
SuperVersion * sv = superversions_to_free_queue_ . front ( ) ;
superversions_to_free_queue_ . pop_front ( ) ;
mutex_ . Unlock ( ) ;
delete sv ;
mutex_ . Lock ( ) ;
}
for ( const auto & file : purge_files_ ) {
for ( const auto & file : purge_files_ ) {
const PurgeFileInfo & purge_file = file . second ;
const PurgeFileInfo & purge_file = file . second ;
const std : : string & fname = purge_file . fname ;
const std : : string & fname = purge_file . fname ;
@ -1366,10 +1373,14 @@ static void CleanupIteratorState(void* arg1, void* /*arg2*/) {
state - > db - > FindObsoleteFiles ( & job_context , false , true ) ;
state - > db - > FindObsoleteFiles ( & job_context , false , true ) ;
if ( state - > background_purge ) {
if ( state - > background_purge ) {
state - > db - > ScheduleBgLogWriterClose ( & job_context ) ;
state - > db - > ScheduleBgLogWriterClose ( & job_context ) ;
state - > db - > AddSuperVersionsToFreeQueue ( state - > super_version ) ;
state - > db - > SchedulePurge ( ) ;
}
}
state - > mu - > Unlock ( ) ;
state - > mu - > Unlock ( ) ;
if ( ! state - > background_purge ) {
delete state - > super_version ;
delete state - > super_version ;
}
if ( job_context . HaveSomethingToDelete ( ) ) {
if ( job_context . HaveSomethingToDelete ( ) ) {
if ( state - > background_purge ) {
if ( state - > background_purge ) {
// PurgeObsoleteFiles here does not delete files. Instead, it adds the
// PurgeObsoleteFiles here does not delete files. Instead, it adds the
@ -2444,7 +2455,7 @@ Iterator* DBImpl::NewIterator(const ReadOptions& read_options,
result = nullptr ;
result = nullptr ;
# else
# else
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( this ) ;
auto iter = new ForwardIterator ( this , read_options , cfd , sv ) ;
auto iter = new ForwardIterator ( this , read_options , cfd , sv ) ;
result = NewDBIterator (
result = NewDBIterator (
env_ , read_options , * cfd - > ioptions ( ) , sv - > mutable_cf_options ,
env_ , read_options , * cfd - > ioptions ( ) , sv - > mutable_cf_options ,
@ -2470,7 +2481,7 @@ ArenaWrappedDBIter* DBImpl::NewIteratorImpl(const ReadOptions& read_options,
ReadCallback * read_callback ,
ReadCallback * read_callback ,
bool allow_blob ,
bool allow_blob ,
bool allow_refresh ) {
bool allow_refresh ) {
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( this ) ;
// Try to generate a DB iterator tree in continuous memory area to be
// Try to generate a DB iterator tree in continuous memory area to be
// cache friendly. Here is an example of result:
// cache friendly. Here is an example of result:
@ -2549,7 +2560,7 @@ Status DBImpl::NewIterators(
# else
# else
for ( auto cfh : column_families ) {
for ( auto cfh : column_families ) {
auto cfd = reinterpret_cast < ColumnFamilyHandleImpl * > ( cfh ) - > cfd ( ) ;
auto cfd = reinterpret_cast < ColumnFamilyHandleImpl * > ( cfh ) - > cfd ( ) ;
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( this ) ;
auto iter = new ForwardIterator ( this , read_options , cfd , sv ) ;
auto iter = new ForwardIterator ( this , read_options , cfd , sv ) ;
iterators - > push_back ( NewDBIterator (
iterators - > push_back ( NewDBIterator (
env_ , read_options , * cfd - > ioptions ( ) , sv - > mutable_cf_options ,
env_ , read_options , * cfd - > ioptions ( ) , sv - > mutable_cf_options ,
@ -2885,7 +2896,7 @@ bool DBImpl::GetAggregatedIntProperty(const Slice& property,
SuperVersion * DBImpl : : GetAndRefSuperVersion ( ColumnFamilyData * cfd ) {
SuperVersion * DBImpl : : GetAndRefSuperVersion ( ColumnFamilyData * cfd ) {
// TODO(ljin): consider using GetReferencedSuperVersion() directly
// TODO(ljin): consider using GetReferencedSuperVersion() directly
return cfd - > GetThreadLocalSuperVersion ( & mutex_ ) ;
return cfd - > GetThreadLocalSuperVersion ( this ) ;
}
}
// REQUIRED: this function should only be called on the write thread or if the
// REQUIRED: this function should only be called on the write thread or if the
@ -2903,11 +2914,19 @@ SuperVersion* DBImpl::GetAndRefSuperVersion(uint32_t column_family_id) {
void DBImpl : : CleanupSuperVersion ( SuperVersion * sv ) {
void DBImpl : : CleanupSuperVersion ( SuperVersion * sv ) {
// Release SuperVersion
// Release SuperVersion
if ( sv - > Unref ( ) ) {
if ( sv - > Unref ( ) ) {
bool defer_purge =
immutable_db_options ( ) . avoid_unnecessary_blocking_io ;
{
{
InstrumentedMutexLock l ( & mutex_ ) ;
InstrumentedMutexLock l ( & mutex_ ) ;
sv - > Cleanup ( ) ;
sv - > Cleanup ( ) ;
if ( defer_purge ) {
AddSuperVersionsToFreeQueue ( sv ) ;
SchedulePurge ( ) ;
}
}
}
if ( ! defer_purge ) {
delete sv ;
delete sv ;
}
RecordTick ( stats_ , NUMBER_SUPERVERSION_CLEANUPS ) ;
RecordTick ( stats_ , NUMBER_SUPERVERSION_CLEANUPS ) ;
}
}
RecordTick ( stats_ , NUMBER_SUPERVERSION_RELEASES ) ;
RecordTick ( stats_ , NUMBER_SUPERVERSION_RELEASES ) ;
@ -3918,7 +3937,7 @@ Status DBImpl::IngestExternalFiles(
start_file_number + = args [ i - 1 ] . external_files . size ( ) ;
start_file_number + = args [ i - 1 ] . external_files . size ( ) ;
auto * cfd =
auto * cfd =
static_cast < ColumnFamilyHandleImpl * > ( args [ i ] . column_family ) - > cfd ( ) ;
static_cast < ColumnFamilyHandleImpl * > ( args [ i ] . column_family ) - > cfd ( ) ;
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( this ) ;
exec_results [ i ] . second = ingestion_jobs [ i ] . Prepare (
exec_results [ i ] . second = ingestion_jobs [ i ] . Prepare (
args [ i ] . external_files , start_file_number , super_version ) ;
args [ i ] . external_files , start_file_number , super_version ) ;
exec_results [ i ] . first = true ;
exec_results [ i ] . first = true ;
@ -3929,7 +3948,7 @@ Status DBImpl::IngestExternalFiles(
{
{
auto * cfd =
auto * cfd =
static_cast < ColumnFamilyHandleImpl * > ( args [ 0 ] . column_family ) - > cfd ( ) ;
static_cast < ColumnFamilyHandleImpl * > ( args [ 0 ] . column_family ) - > cfd ( ) ;
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( this ) ;
exec_results [ 0 ] . second = ingestion_jobs [ 0 ] . Prepare (
exec_results [ 0 ] . second = ingestion_jobs [ 0 ] . Prepare (
args [ 0 ] . external_files , next_file_number , super_version ) ;
args [ 0 ] . external_files , next_file_number , super_version ) ;
exec_results [ 0 ] . first = true ;
exec_results [ 0 ] . first = true ;
@ -4205,7 +4224,7 @@ Status DBImpl::CreateColumnFamilyWithImport(
dummy_sv_ctx . Clean ( ) ;
dummy_sv_ctx . Clean ( ) ;
if ( status . ok ( ) ) {
if ( status . ok ( ) ) {
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * sv = cfd - > GetReferencedSuperVersion ( this ) ;
status = import_job . Prepare ( next_file_number , sv ) ;
status = import_job . Prepare ( next_file_number , sv ) ;
CleanupSuperVersion ( sv ) ;
CleanupSuperVersion ( sv ) ;
}
}
@ -4282,7 +4301,7 @@ Status DBImpl::VerifyChecksum(const ReadOptions& read_options) {
}
}
std : : vector < SuperVersion * > sv_list ;
std : : vector < SuperVersion * > sv_list ;
for ( auto cfd : cfd_list ) {
for ( auto cfd : cfd_list ) {
sv_list . push_back ( cfd - > GetReferencedSuperVersion ( & mutex_ ) ) ;
sv_list . push_back ( cfd - > GetReferencedSuperVersion ( this ) ) ;
}
}
for ( auto & sv : sv_list ) {
for ( auto & sv : sv_list ) {
VersionStorageInfo * vstorage = sv - > current - > storage_info ( ) ;
VersionStorageInfo * vstorage = sv - > current - > storage_info ( ) ;
@ -4307,14 +4326,23 @@ Status DBImpl::VerifyChecksum(const ReadOptions& read_options) {
break ;
break ;
}
}
}
}
bool defer_purge =
immutable_db_options ( ) . avoid_unnecessary_blocking_io ;
{
{
InstrumentedMutexLock l ( & mutex_ ) ;
InstrumentedMutexLock l ( & mutex_ ) ;
for ( auto sv : sv_list ) {
for ( auto sv : sv_list ) {
if ( sv & & sv - > Unref ( ) ) {
if ( sv & & sv - > Unref ( ) ) {
sv - > Cleanup ( ) ;
sv - > Cleanup ( ) ;
if ( defer_purge ) {
AddSuperVersionsToFreeQueue ( sv ) ;
} else {
delete sv ;
delete sv ;
}
}
}
}
}
if ( defer_purge ) {
SchedulePurge ( ) ;
}
for ( auto cfd : cfd_list ) {
for ( auto cfd : cfd_list ) {
cfd - > UnrefAndTryDelete ( ) ;
cfd - > UnrefAndTryDelete ( ) ;
}
}