delete_scheduler.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #pragma once
  6. #ifndef ROCKSDB_LITE
  7. #include <map>
  8. #include <queue>
  9. #include <string>
  10. #include <thread>
  11. #include "monitoring/instrumented_mutex.h"
  12. #include "port/port.h"
  13. #include "rocksdb/file_system.h"
  14. #include "rocksdb/status.h"
  15. namespace ROCKSDB_NAMESPACE {
  16. class Env;
  17. class Logger;
  18. class SstFileManagerImpl;
  19. // DeleteScheduler allows the DB to enforce a rate limit on file deletion,
  20. // Instead of deleteing files immediately, files are marked as trash
  21. // and deleted in a background thread that apply sleep penlty between deletes
  22. // if they are happening in a rate faster than rate_bytes_per_sec,
  23. //
  24. // Rate limiting can be turned off by setting rate_bytes_per_sec = 0, In this
  25. // case DeleteScheduler will delete files immediately.
  26. class DeleteScheduler {
  27. public:
  28. DeleteScheduler(Env* env, FileSystem* fs, int64_t rate_bytes_per_sec,
  29. Logger* info_log, SstFileManagerImpl* sst_file_manager,
  30. double max_trash_db_ratio, uint64_t bytes_max_delete_chunk);
  31. ~DeleteScheduler();
  32. // Return delete rate limit in bytes per second
  33. int64_t GetRateBytesPerSecond() { return rate_bytes_per_sec_.load(); }
  34. // Set delete rate limit in bytes per second
  35. void SetRateBytesPerSecond(int64_t bytes_per_sec) {
  36. rate_bytes_per_sec_.store(bytes_per_sec);
  37. }
  38. // Mark file as trash directory and schedule it's deletion. If force_bg is
  39. // set, it forces the file to always be deleted in the background thread,
  40. // except when rate limiting is disabled
  41. Status DeleteFile(const std::string& fname, const std::string& dir_to_sync,
  42. const bool force_bg = false);
  43. // Wait for all files being deleteing in the background to finish or for
  44. // destructor to be called.
  45. void WaitForEmptyTrash();
  46. // Return a map containing errors that happened in BackgroundEmptyTrash
  47. // file_path => error status
  48. std::map<std::string, Status> GetBackgroundErrors();
  49. uint64_t GetTotalTrashSize() { return total_trash_size_.load(); }
  50. // Return trash/DB size ratio where new files will be deleted immediately
  51. double GetMaxTrashDBRatio() {
  52. return max_trash_db_ratio_.load();
  53. }
  54. // Update trash/DB size ratio where new files will be deleted immediately
  55. void SetMaxTrashDBRatio(double r) {
  56. assert(r >= 0);
  57. max_trash_db_ratio_.store(r);
  58. }
  59. static const std::string kTrashExtension;
  60. static bool IsTrashFile(const std::string& file_path);
  61. // Check if there are any .trash filse in path, and schedule their deletion
  62. // Or delete immediately if sst_file_manager is nullptr
  63. static Status CleanupDirectory(Env* env, SstFileManagerImpl* sfm,
  64. const std::string& path);
  65. private:
  66. Status MarkAsTrash(const std::string& file_path, std::string* path_in_trash);
  67. Status DeleteTrashFile(const std::string& path_in_trash,
  68. const std::string& dir_to_sync,
  69. uint64_t* deleted_bytes, bool* is_complete);
  70. void BackgroundEmptyTrash();
  71. Env* env_;
  72. FileSystem* fs_;
  73. // total size of trash files
  74. std::atomic<uint64_t> total_trash_size_;
  75. // Maximum number of bytes that should be deleted per second
  76. std::atomic<int64_t> rate_bytes_per_sec_;
  77. // Mutex to protect queue_, pending_files_, bg_errors_, closing_
  78. InstrumentedMutex mu_;
  79. struct FileAndDir {
  80. FileAndDir(const std::string& f, const std::string& d) : fname(f), dir(d) {}
  81. std::string fname;
  82. std::string dir; // empty will be skipped.
  83. };
  84. // Queue of trash files that need to be deleted
  85. std::queue<FileAndDir> queue_;
  86. // Number of trash files that are waiting to be deleted
  87. int32_t pending_files_;
  88. uint64_t bytes_max_delete_chunk_;
  89. // Errors that happened in BackgroundEmptyTrash (file_path => error)
  90. std::map<std::string, Status> bg_errors_;
  91. bool num_link_error_printed_ = false;
  92. // Set to true in ~DeleteScheduler() to force BackgroundEmptyTrash to stop
  93. bool closing_;
  94. // Condition variable signaled in these conditions
  95. // - pending_files_ value change from 0 => 1
  96. // - pending_files_ value change from 1 => 0
  97. // - closing_ value is set to true
  98. InstrumentedCondVar cv_;
  99. // Background thread running BackgroundEmptyTrash
  100. std::unique_ptr<port::Thread> bg_thread_;
  101. // Mutex to protect threads from file name conflicts
  102. InstrumentedMutex file_move_mu_;
  103. Logger* info_log_;
  104. SstFileManagerImpl* sst_file_manager_;
  105. // If the trash size constitutes for more than this fraction of the total DB
  106. // size we will start deleting new files passed to DeleteScheduler
  107. // immediately
  108. std::atomic<double> max_trash_db_ratio_;
  109. static const uint64_t kMicrosInSecond = 1000 * 1000LL;
  110. };
  111. } // namespace ROCKSDB_NAMESPACE
  112. #endif // ROCKSDB_LITE