diff --git a/db/db_impl/db_impl.cc b/db/db_impl/db_impl.cc index 5b830c363..1df439569 100644 --- a/db/db_impl/db_impl.cc +++ b/db/db_impl/db_impl.cc @@ -1321,19 +1321,26 @@ void DBImpl::BackgroundCallPurge() { delete sv; mutex_.Lock(); } - for (const auto& file : purge_files_) { - const PurgeFileInfo& purge_file = file.second; + + // Can't use iterator to go over purge_files_ because inside the loop we're + // unlocking the mutex that protects purge_files_. + while (!purge_files_.empty()) { + auto it = purge_files_.begin(); + // Need to make a copy of the PurgeFilesInfo before unlocking the mutex. + PurgeFileInfo purge_file = it->second; + const std::string& fname = purge_file.fname; const std::string& dir_to_sync = purge_file.dir_to_sync; FileType type = purge_file.type; uint64_t number = purge_file.number; int job_id = purge_file.job_id; + purge_files_.erase(it); + mutex_.Unlock(); DeleteObsoleteFileImpl(job_id, fname, dir_to_sync, type, number); mutex_.Lock(); } - purge_files_.clear(); bg_purge_scheduled_--; diff --git a/db/db_impl/db_impl.h b/db/db_impl/db_impl.h index d8c5e1c60..bbfecb3a6 100644 --- a/db/db_impl/db_impl.h +++ b/db/db_impl/db_impl.h @@ -1201,7 +1201,7 @@ class DBImpl : public DB { }; // PurgeFileInfo is a structure to hold information of files to be deleted in - // purge_queue_ + // purge_files_ struct PurgeFileInfo { std::string fname; std::string dir_to_sync; diff --git a/file/delete_scheduler.cc b/file/delete_scheduler.cc index d528d6713..23bc5fcea 100644 --- a/file/delete_scheduler.cc +++ b/file/delete_scheduler.cc @@ -74,7 +74,8 @@ Status DeleteScheduler::DeleteFile(const std::string& file_path, s = MarkAsTrash(file_path, &trash_file); if (!s.ok()) { - ROCKS_LOG_ERROR(info_log_, "Failed to mark %s as trash", file_path.c_str()); + ROCKS_LOG_ERROR(info_log_, "Failed to mark %s as trash -- %s", + file_path.c_str(), s.ToString().c_str()); s = fs_->DeleteFile(file_path, IOOptions(), nullptr); if (s.ok()) { sst_file_manager_->OnDeleteFile(file_path);