db_stress_env_wrapper.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #ifdef GFLAGS
  10. #pragma once
  11. #include "db_stress_tool/db_stress_common.h"
  12. #include "monitoring/thread_status_util.h"
  13. namespace ROCKSDB_NAMESPACE {
  14. namespace {
  15. void CheckIOActivity(const IOOptions& options) {
  16. #ifndef NDEBUG
  17. const ThreadStatus::OperationType thread_op =
  18. ThreadStatusUtil::GetThreadOperation();
  19. Env::IOActivity io_activity =
  20. ThreadStatusUtil::TEST_GetExpectedIOActivity(thread_op);
  21. assert(io_activity == Env::IOActivity::kUnknown ||
  22. io_activity == options.io_activity);
  23. #else
  24. (void)options;
  25. #endif
  26. }
  27. } // namespace
  28. class DbStressRandomAccessFileWrapper : public FSRandomAccessFileOwnerWrapper {
  29. public:
  30. explicit DbStressRandomAccessFileWrapper(
  31. std::unique_ptr<FSRandomAccessFile>&& target)
  32. : FSRandomAccessFileOwnerWrapper(std::move(target)) {}
  33. IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
  34. Slice* result, char* scratch,
  35. IODebugContext* dbg) const override {
  36. #ifndef NDEBUG
  37. const ThreadStatus::OperationType thread_op =
  38. ThreadStatusUtil::GetThreadOperation();
  39. Env::IOActivity io_activity =
  40. ThreadStatusUtil::TEST_GetExpectedIOActivity(thread_op);
  41. assert(io_activity == Env::IOActivity::kUnknown ||
  42. io_activity == options.io_activity);
  43. #endif
  44. return target()->Read(offset, n, options, result, scratch, dbg);
  45. }
  46. IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
  47. const IOOptions& options, IODebugContext* dbg) override {
  48. #ifndef NDEBUG
  49. const ThreadStatus::OperationType thread_op =
  50. ThreadStatusUtil::GetThreadOperation();
  51. Env::IOActivity io_activity =
  52. ThreadStatusUtil::TEST_GetExpectedIOActivity(thread_op);
  53. assert(io_activity == Env::IOActivity::kUnknown ||
  54. io_activity == options.io_activity);
  55. #endif
  56. return target()->MultiRead(reqs, num_reqs, options, dbg);
  57. }
  58. IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& options,
  59. IODebugContext* dbg) override {
  60. #ifndef NDEBUG
  61. const ThreadStatus::OperationType thread_op =
  62. ThreadStatusUtil::GetThreadOperation();
  63. Env::IOActivity io_activity =
  64. ThreadStatusUtil::TEST_GetExpectedIOActivity(thread_op);
  65. assert(io_activity == Env::IOActivity::kUnknown ||
  66. io_activity == options.io_activity);
  67. #endif
  68. return target()->Prefetch(offset, n, options, dbg);
  69. }
  70. IOStatus ReadAsync(FSReadRequest& req, const IOOptions& options,
  71. std::function<void(FSReadRequest&, void*)> cb,
  72. void* cb_arg, void** io_handle, IOHandleDeleter* del_fn,
  73. IODebugContext* dbg) override {
  74. #ifndef NDEBUG
  75. const ThreadStatus::OperationType thread_op =
  76. ThreadStatusUtil::GetThreadOperation();
  77. Env::IOActivity io_activity =
  78. ThreadStatusUtil::TEST_GetExpectedIOActivity(thread_op);
  79. assert(io_activity == Env::IOActivity::kUnknown ||
  80. io_activity == options.io_activity);
  81. #endif
  82. return target()->ReadAsync(req, options, cb, cb_arg, io_handle, del_fn,
  83. dbg);
  84. }
  85. };
  86. class DbStressWritableFileWrapper : public FSWritableFileOwnerWrapper {
  87. public:
  88. explicit DbStressWritableFileWrapper(std::unique_ptr<FSWritableFile>&& target)
  89. : FSWritableFileOwnerWrapper(std::move(target)) {}
  90. IOStatus Append(const Slice& data, const IOOptions& options,
  91. IODebugContext* dbg) override {
  92. CheckIOActivity(options);
  93. return target()->Append(data, options, dbg);
  94. }
  95. IOStatus Append(const Slice& data, const IOOptions& options,
  96. const DataVerificationInfo& verification_info,
  97. IODebugContext* dbg) override {
  98. CheckIOActivity(options);
  99. return target()->Append(data, options, verification_info, dbg);
  100. }
  101. IOStatus PositionedAppend(const Slice& data, uint64_t offset,
  102. const IOOptions& options,
  103. IODebugContext* dbg) override {
  104. CheckIOActivity(options);
  105. return target()->PositionedAppend(data, offset, options, dbg);
  106. }
  107. IOStatus PositionedAppend(const Slice& data, uint64_t offset,
  108. const IOOptions& options,
  109. const DataVerificationInfo& verification_info,
  110. IODebugContext* dbg) override {
  111. CheckIOActivity(options);
  112. return target()->PositionedAppend(data, offset, options, verification_info,
  113. dbg);
  114. }
  115. IOStatus Truncate(uint64_t size, const IOOptions& options,
  116. IODebugContext* dbg) override {
  117. CheckIOActivity(options);
  118. return target()->Truncate(size, options, dbg);
  119. }
  120. IOStatus Close(const IOOptions& options, IODebugContext* dbg) override {
  121. CheckIOActivity(options);
  122. return target()->Close(options, dbg);
  123. }
  124. IOStatus Flush(const IOOptions& options, IODebugContext* dbg) override {
  125. CheckIOActivity(options);
  126. return target()->Flush(options, dbg);
  127. }
  128. IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override {
  129. CheckIOActivity(options);
  130. return target()->Sync(options, dbg);
  131. }
  132. IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override {
  133. CheckIOActivity(options);
  134. return target()->Fsync(options, dbg);
  135. }
  136. #ifdef ROCKSDB_FALLOCATE_PRESENT
  137. IOStatus Allocate(uint64_t offset, uint64_t len, const IOOptions& options,
  138. IODebugContext* dbg) override {
  139. CheckIOActivity(options);
  140. return target()->Allocate(offset, len, options, dbg);
  141. }
  142. #endif
  143. IOStatus RangeSync(uint64_t offset, uint64_t nbytes, const IOOptions& options,
  144. IODebugContext* dbg) override {
  145. CheckIOActivity(options);
  146. return target()->RangeSync(offset, nbytes, options, dbg);
  147. }
  148. };
  149. class DbStressFSWrapper : public FileSystemWrapper {
  150. public:
  151. explicit DbStressFSWrapper(const std::shared_ptr<FileSystem>& t)
  152. : FileSystemWrapper(t) {}
  153. static const char* kClassName() { return "DbStressFS"; }
  154. const char* Name() const override { return kClassName(); }
  155. IOStatus NewRandomAccessFile(const std::string& f,
  156. const FileOptions& file_opts,
  157. std::unique_ptr<FSRandomAccessFile>* r,
  158. IODebugContext* dbg) override {
  159. std::unique_ptr<FSRandomAccessFile> file;
  160. IOStatus s = target()->NewRandomAccessFile(f, file_opts, &file, dbg);
  161. if (s.ok()) {
  162. r->reset(new DbStressRandomAccessFileWrapper(std::move(file)));
  163. }
  164. return s;
  165. }
  166. IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
  167. std::unique_ptr<FSWritableFile>* r,
  168. IODebugContext* dbg) override {
  169. std::unique_ptr<FSWritableFile> file;
  170. IOStatus s = target()->NewWritableFile(f, file_opts, &file, dbg);
  171. if (s.ok()) {
  172. r->reset(new DbStressWritableFileWrapper(std::move(file)));
  173. }
  174. return s;
  175. }
  176. IOStatus DeleteFile(const std::string& f, const IOOptions& opts,
  177. IODebugContext* dbg) override {
  178. // We determine whether it is a manifest file by searching a strong,
  179. // so that there will be false positive if the directory path contains the
  180. // keyword but it is unlikely.
  181. // Checkpoint, backup, and restore directories needs to be exempted.
  182. if (!if_preserve_all_manifests ||
  183. f.find("MANIFEST-") == std::string::npos ||
  184. f.find("checkpoint") != std::string::npos ||
  185. f.find(".backup") != std::string::npos ||
  186. f.find(".restore") != std::string::npos) {
  187. return target()->DeleteFile(f, opts, dbg);
  188. }
  189. // Rename the file instead of deletion to keep the history, and
  190. // at the same time it is not visible to RocksDB.
  191. return target()->RenameFile(f, f + "_renamed_", opts, dbg);
  192. }
  193. // If true, all manifest files will not be delted in DeleteFile().
  194. bool if_preserve_all_manifests = true;
  195. };
  196. } // namespace ROCKSDB_NAMESPACE
  197. #endif // GFLAGS