db_filesnapshot.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. //
  6. #ifndef ROCKSDB_LITE
  7. #include <stdint.h>
  8. #include <algorithm>
  9. #include <cinttypes>
  10. #include <string>
  11. #include "db/db_impl/db_impl.h"
  12. #include "db/job_context.h"
  13. #include "db/version_set.h"
  14. #include "file/file_util.h"
  15. #include "file/filename.h"
  16. #include "port/port.h"
  17. #include "rocksdb/db.h"
  18. #include "rocksdb/env.h"
  19. #include "test_util/sync_point.h"
  20. #include "util/mutexlock.h"
  21. namespace ROCKSDB_NAMESPACE {
  22. Status DBImpl::DisableFileDeletions() {
  23. InstrumentedMutexLock l(&mutex_);
  24. ++disable_delete_obsolete_files_;
  25. if (disable_delete_obsolete_files_ == 1) {
  26. ROCKS_LOG_INFO(immutable_db_options_.info_log, "File Deletions Disabled");
  27. } else {
  28. ROCKS_LOG_WARN(immutable_db_options_.info_log,
  29. "File Deletions Disabled, but already disabled. Counter: %d",
  30. disable_delete_obsolete_files_);
  31. }
  32. return Status::OK();
  33. }
  34. Status DBImpl::EnableFileDeletions(bool force) {
  35. // Job id == 0 means that this is not our background process, but rather
  36. // user thread
  37. JobContext job_context(0);
  38. bool file_deletion_enabled = false;
  39. {
  40. InstrumentedMutexLock l(&mutex_);
  41. if (force) {
  42. // if force, we need to enable file deletions right away
  43. disable_delete_obsolete_files_ = 0;
  44. } else if (disable_delete_obsolete_files_ > 0) {
  45. --disable_delete_obsolete_files_;
  46. }
  47. if (disable_delete_obsolete_files_ == 0) {
  48. file_deletion_enabled = true;
  49. FindObsoleteFiles(&job_context, true);
  50. bg_cv_.SignalAll();
  51. }
  52. }
  53. if (file_deletion_enabled) {
  54. ROCKS_LOG_INFO(immutable_db_options_.info_log, "File Deletions Enabled");
  55. if (job_context.HaveSomethingToDelete()) {
  56. PurgeObsoleteFiles(job_context);
  57. }
  58. } else {
  59. ROCKS_LOG_WARN(immutable_db_options_.info_log,
  60. "File Deletions Enable, but not really enabled. Counter: %d",
  61. disable_delete_obsolete_files_);
  62. }
  63. job_context.Clean();
  64. LogFlush(immutable_db_options_.info_log);
  65. return Status::OK();
  66. }
  67. int DBImpl::IsFileDeletionsEnabled() const {
  68. return !disable_delete_obsolete_files_;
  69. }
  70. Status DBImpl::GetLiveFiles(std::vector<std::string>& ret,
  71. uint64_t* manifest_file_size,
  72. bool flush_memtable) {
  73. *manifest_file_size = 0;
  74. mutex_.Lock();
  75. if (flush_memtable) {
  76. // flush all dirty data to disk.
  77. Status status;
  78. if (immutable_db_options_.atomic_flush) {
  79. autovector<ColumnFamilyData*> cfds;
  80. SelectColumnFamiliesForAtomicFlush(&cfds);
  81. mutex_.Unlock();
  82. status = AtomicFlushMemTables(cfds, FlushOptions(),
  83. FlushReason::kGetLiveFiles);
  84. mutex_.Lock();
  85. } else {
  86. for (auto cfd : *versions_->GetColumnFamilySet()) {
  87. if (cfd->IsDropped()) {
  88. continue;
  89. }
  90. cfd->Ref();
  91. mutex_.Unlock();
  92. status = FlushMemTable(cfd, FlushOptions(), FlushReason::kGetLiveFiles);
  93. TEST_SYNC_POINT("DBImpl::GetLiveFiles:1");
  94. TEST_SYNC_POINT("DBImpl::GetLiveFiles:2");
  95. mutex_.Lock();
  96. cfd->UnrefAndTryDelete();
  97. if (!status.ok()) {
  98. break;
  99. }
  100. }
  101. }
  102. versions_->GetColumnFamilySet()->FreeDeadColumnFamilies();
  103. if (!status.ok()) {
  104. mutex_.Unlock();
  105. ROCKS_LOG_ERROR(immutable_db_options_.info_log, "Cannot Flush data %s\n",
  106. status.ToString().c_str());
  107. return status;
  108. }
  109. }
  110. // Make a set of all of the live *.sst files
  111. std::vector<FileDescriptor> live;
  112. for (auto cfd : *versions_->GetColumnFamilySet()) {
  113. if (cfd->IsDropped()) {
  114. continue;
  115. }
  116. cfd->current()->AddLiveFiles(&live);
  117. }
  118. ret.clear();
  119. ret.reserve(live.size() + 3); // *.sst + CURRENT + MANIFEST + OPTIONS
  120. // create names of the live files. The names are not absolute
  121. // paths, instead they are relative to dbname_;
  122. for (const auto& live_file : live) {
  123. ret.push_back(MakeTableFileName("", live_file.GetNumber()));
  124. }
  125. ret.push_back(CurrentFileName(""));
  126. ret.push_back(DescriptorFileName("", versions_->manifest_file_number()));
  127. ret.push_back(OptionsFileName("", versions_->options_file_number()));
  128. // find length of manifest file while holding the mutex lock
  129. *manifest_file_size = versions_->manifest_file_size();
  130. mutex_.Unlock();
  131. return Status::OK();
  132. }
  133. Status DBImpl::GetSortedWalFiles(VectorLogPtr& files) {
  134. {
  135. // If caller disabled deletions, this function should return files that are
  136. // guaranteed not to be deleted until deletions are re-enabled. We need to
  137. // wait for pending purges to finish since WalManager doesn't know which
  138. // files are going to be purged. Additional purges won't be scheduled as
  139. // long as deletions are disabled (so the below loop must terminate).
  140. InstrumentedMutexLock l(&mutex_);
  141. while (disable_delete_obsolete_files_ > 0 &&
  142. pending_purge_obsolete_files_ > 0) {
  143. bg_cv_.Wait();
  144. }
  145. }
  146. return wal_manager_.GetSortedWalFiles(files);
  147. }
  148. Status DBImpl::GetCurrentWalFile(std::unique_ptr<LogFile>* current_log_file) {
  149. uint64_t current_logfile_number;
  150. {
  151. InstrumentedMutexLock l(&mutex_);
  152. current_logfile_number = logfile_number_;
  153. }
  154. return wal_manager_.GetLiveWalFile(current_logfile_number, current_log_file);
  155. }
  156. } // namespace ROCKSDB_NAMESPACE
  157. #endif // ROCKSDB_LITE