// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). #pragma once #ifndef ROCKSDB_LITE #include #include #include #include #include "monitoring/instrumented_mutex.h" #include "port/port.h" #include "rocksdb/status.h" namespace rocksdb { class Env; class Logger; class SstFileManagerImpl; // DeleteScheduler allows the DB to enforce a rate limit on file deletion, // Instead of deleteing files immediately, files are moved to trash_dir // and deleted in a background thread that apply sleep penlty between deletes // if they are happening in a rate faster than rate_bytes_per_sec, // // Rate limiting can be turned off by setting rate_bytes_per_sec = 0, In this // case DeleteScheduler will delete files immediately. class DeleteScheduler { public: DeleteScheduler(Env* env, const std::string& trash_dir, int64_t rate_bytes_per_sec, Logger* info_log, SstFileManagerImpl* sst_file_manager); ~DeleteScheduler(); // Return delete rate limit in bytes per second int64_t GetRateBytesPerSecond() { return rate_bytes_per_sec_.load(); } // Set delete rate limit in bytes per second void SetRateBytesPerSecond(int64_t bytes_per_sec) { return rate_bytes_per_sec_.store(bytes_per_sec); } // Move file to trash directory and schedule it's deletion Status DeleteFile(const std::string& fname); // Wait for all files being deleteing in the background to finish or for // destructor to be called. void WaitForEmptyTrash(); // Return a map containing errors that happened in BackgroundEmptyTrash // file_path => error status std::map GetBackgroundErrors(); uint64_t GetTotalTrashSize() { return total_trash_size_.load(); } void TEST_SetMaxTrashDBRatio(double r) { assert(r >= 0); max_trash_db_ratio_ = r; } private: Status MoveToTrash(const std::string& file_path, std::string* path_in_trash); Status DeleteTrashFile(const std::string& path_in_trash, uint64_t* deleted_bytes); void BackgroundEmptyTrash(); Env* env_; // Path to the trash directory std::string trash_dir_; // total size of trash directory std::atomic total_trash_size_; // Maximum number of bytes that should be deleted per second std::atomic rate_bytes_per_sec_; // Mutex to protect queue_, pending_files_, bg_errors_, closing_ InstrumentedMutex mu_; // Queue of files in trash that need to be deleted std::queue queue_; // Number of files in trash that are waiting to be deleted int32_t pending_files_; // Errors that happened in BackgroundEmptyTrash (file_path => error) std::map bg_errors_; // Set to true in ~DeleteScheduler() to force BackgroundEmptyTrash to stop bool closing_; // Condition variable signaled in these conditions // - pending_files_ value change from 0 => 1 // - pending_files_ value change from 1 => 0 // - closing_ value is set to true InstrumentedCondVar cv_; // Background thread running BackgroundEmptyTrash std::unique_ptr bg_thread_; // Mutex to protect threads from file name conflicts InstrumentedMutex file_move_mu_; Logger* info_log_; SstFileManagerImpl* sst_file_manager_; // If the trash size constitutes for more than 25% of the total DB size // we will start deleting new files passed to DeleteScheduler immediately double max_trash_db_ratio_ = 0.25; static const uint64_t kMicrosInSecond = 1000 * 1000LL; }; } // namespace rocksdb #endif // ROCKSDB_LITE