blob_file.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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 <atomic>
  8. #include <limits>
  9. #include <memory>
  10. #include <unordered_set>
  11. #include "file/random_access_file_reader.h"
  12. #include "port/port.h"
  13. #include "rocksdb/env.h"
  14. #include "rocksdb/options.h"
  15. #include "utilities/blob_db/blob_log_format.h"
  16. #include "utilities/blob_db/blob_log_reader.h"
  17. #include "utilities/blob_db/blob_log_writer.h"
  18. namespace ROCKSDB_NAMESPACE {
  19. namespace blob_db {
  20. class BlobDBImpl;
  21. class BlobFile {
  22. friend class BlobDBImpl;
  23. friend struct BlobFileComparator;
  24. friend struct BlobFileComparatorTTL;
  25. friend class BlobIndexCompactionFilterGC;
  26. private:
  27. // access to parent
  28. const BlobDBImpl* parent_{nullptr};
  29. // path to blob directory
  30. std::string path_to_dir_;
  31. // the id of the file.
  32. // the above 2 are created during file creation and never changed
  33. // after that
  34. uint64_t file_number_{0};
  35. // The file numbers of the SST files whose oldest blob file reference
  36. // points to this blob file.
  37. std::unordered_set<uint64_t> linked_sst_files_;
  38. // Info log.
  39. Logger* info_log_{nullptr};
  40. // Column family id.
  41. uint32_t column_family_id_{std::numeric_limits<uint32_t>::max()};
  42. // Compression type of blobs in the file
  43. CompressionType compression_{kNoCompression};
  44. // If true, the keys in this file all has TTL. Otherwise all keys don't
  45. // have TTL.
  46. bool has_ttl_{false};
  47. // TTL range of blobs in the file.
  48. ExpirationRange expiration_range_;
  49. // number of blobs in the file
  50. std::atomic<uint64_t> blob_count_{0};
  51. // size of the file
  52. std::atomic<uint64_t> file_size_{0};
  53. BlobLogHeader header_;
  54. // closed_ = true implies the file is no more mutable
  55. // no more blobs will be appended and the footer has been written out
  56. std::atomic<bool> closed_{false};
  57. // The latest sequence number when the file was closed/made immutable.
  58. SequenceNumber immutable_sequence_{0};
  59. // Whether the file was marked obsolete (due to either TTL or GC).
  60. // obsolete_ still needs to do iterator/snapshot checks
  61. std::atomic<bool> obsolete_{false};
  62. // The last sequence number by the time the file marked as obsolete.
  63. // Data in this file is visible to a snapshot taken before the sequence.
  64. SequenceNumber obsolete_sequence_{0};
  65. // Sequential/Append writer for blobs
  66. std::shared_ptr<Writer> log_writer_;
  67. // random access file reader for GET calls
  68. std::shared_ptr<RandomAccessFileReader> ra_file_reader_;
  69. // This Read-Write mutex is per file specific and protects
  70. // all the datastructures
  71. mutable port::RWMutex mutex_;
  72. // time when the random access reader was last created.
  73. std::atomic<std::int64_t> last_access_{-1};
  74. // last time file was fsync'd/fdatasyncd
  75. std::atomic<uint64_t> last_fsync_{0};
  76. bool header_valid_{false};
  77. bool footer_valid_{false};
  78. public:
  79. BlobFile() = default;
  80. BlobFile(const BlobDBImpl* parent, const std::string& bdir, uint64_t fnum,
  81. Logger* info_log);
  82. BlobFile(const BlobDBImpl* parent, const std::string& bdir, uint64_t fnum,
  83. Logger* info_log, uint32_t column_family_id,
  84. CompressionType compression, bool has_ttl,
  85. const ExpirationRange& expiration_range);
  86. ~BlobFile();
  87. uint32_t GetColumnFamilyId() const;
  88. // Returns log file's absolute pathname.
  89. std::string PathName() const;
  90. // Primary identifier for blob file.
  91. // once the file is created, this never changes
  92. uint64_t BlobFileNumber() const { return file_number_; }
  93. // Get the set of SST files whose oldest blob file reference points to
  94. // this file.
  95. const std::unordered_set<uint64_t>& GetLinkedSstFiles() const {
  96. return linked_sst_files_;
  97. }
  98. // Link an SST file whose oldest blob file reference points to this file.
  99. void LinkSstFile(uint64_t sst_file_number) {
  100. assert(linked_sst_files_.find(sst_file_number) == linked_sst_files_.end());
  101. linked_sst_files_.insert(sst_file_number);
  102. }
  103. // Unlink an SST file whose oldest blob file reference points to this file.
  104. void UnlinkSstFile(uint64_t sst_file_number) {
  105. auto it = linked_sst_files_.find(sst_file_number);
  106. assert(it != linked_sst_files_.end());
  107. linked_sst_files_.erase(it);
  108. }
  109. // the following functions are atomic, and don't need
  110. // read lock
  111. uint64_t BlobCount() const {
  112. return blob_count_.load(std::memory_order_acquire);
  113. }
  114. std::string DumpState() const;
  115. // if the file is not taking any more appends.
  116. bool Immutable() const { return closed_.load(); }
  117. // Mark the file as immutable.
  118. // REQUIRES: write lock held, or access from single thread (on DB open).
  119. void MarkImmutable(SequenceNumber sequence) {
  120. closed_ = true;
  121. immutable_sequence_ = sequence;
  122. }
  123. SequenceNumber GetImmutableSequence() const {
  124. assert(Immutable());
  125. return immutable_sequence_;
  126. }
  127. // Whether the file was marked obsolete (due to either TTL or GC).
  128. bool Obsolete() const {
  129. assert(Immutable() || !obsolete_.load());
  130. return obsolete_.load();
  131. }
  132. // Mark file as obsolete (due to either TTL or GC). The file is not visible to
  133. // snapshots with sequence greater or equal to the given sequence.
  134. void MarkObsolete(SequenceNumber sequence);
  135. SequenceNumber GetObsoleteSequence() const {
  136. assert(Obsolete());
  137. return obsolete_sequence_;
  138. }
  139. // we will assume this is atomic
  140. bool NeedsFsync(bool hard, uint64_t bytes_per_sync) const;
  141. Status Fsync();
  142. uint64_t GetFileSize() const {
  143. return file_size_.load(std::memory_order_acquire);
  144. }
  145. // All Get functions which are not atomic, will need ReadLock on the mutex
  146. ExpirationRange GetExpirationRange() const { return expiration_range_; }
  147. void ExtendExpirationRange(uint64_t expiration) {
  148. expiration_range_.first = std::min(expiration_range_.first, expiration);
  149. expiration_range_.second = std::max(expiration_range_.second, expiration);
  150. }
  151. bool HasTTL() const { return has_ttl_; }
  152. void SetHasTTL(bool has_ttl) { has_ttl_ = has_ttl; }
  153. CompressionType GetCompressionType() const { return compression_; }
  154. std::shared_ptr<Writer> GetWriter() const { return log_writer_; }
  155. // Read blob file header and footer. Return corruption if file header is
  156. // malform or incomplete. If footer is malform or incomplete, set
  157. // footer_valid_ to false and return Status::OK.
  158. Status ReadMetadata(Env* env, const EnvOptions& env_options);
  159. Status GetReader(Env* env, const EnvOptions& env_options,
  160. std::shared_ptr<RandomAccessFileReader>* reader,
  161. bool* fresh_open);
  162. private:
  163. std::shared_ptr<Reader> OpenRandomAccessReader(
  164. Env* env, const DBOptions& db_options,
  165. const EnvOptions& env_options) const;
  166. Status ReadFooter(BlobLogFooter* footer);
  167. Status WriteFooterAndCloseLocked(SequenceNumber sequence);
  168. void CloseRandomAccessLocked();
  169. // this is used, when you are reading only the footer of a
  170. // previously closed file
  171. Status SetFromFooterLocked(const BlobLogFooter& footer);
  172. void set_expiration_range(const ExpirationRange& expiration_range) {
  173. expiration_range_ = expiration_range;
  174. }
  175. // The following functions are atomic, and don't need locks
  176. void SetFileSize(uint64_t fs) { file_size_ = fs; }
  177. void SetBlobCount(uint64_t bc) { blob_count_ = bc; }
  178. void BlobRecordAdded(uint64_t record_size) {
  179. ++blob_count_;
  180. file_size_ += record_size;
  181. }
  182. };
  183. } // namespace blob_db
  184. } // namespace ROCKSDB_NAMESPACE
  185. #endif // ROCKSDB_LITE