counted_fs.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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. #include "utilities/counted_fs.h"
  6. #include <sstream>
  7. #include "rocksdb/file_system.h"
  8. #include "rocksdb/utilities/options_type.h"
  9. namespace ROCKSDB_NAMESPACE {
  10. namespace {
  11. class CountedSequentialFile : public FSSequentialFileOwnerWrapper {
  12. private:
  13. CountedFileSystem* fs_;
  14. public:
  15. CountedSequentialFile(std::unique_ptr<FSSequentialFile>&& f,
  16. CountedFileSystem* fs)
  17. : FSSequentialFileOwnerWrapper(std::move(f)), fs_(fs) {}
  18. ~CountedSequentialFile() override { fs_->counters()->closes++; }
  19. IOStatus Read(size_t n, const IOOptions& options, Slice* result,
  20. char* scratch, IODebugContext* dbg) override {
  21. IOStatus rv = target()->Read(n, options, result, scratch, dbg);
  22. fs_->counters()->reads.RecordOp(rv, result->size());
  23. return rv;
  24. }
  25. IOStatus PositionedRead(uint64_t offset, size_t n, const IOOptions& options,
  26. Slice* result, char* scratch,
  27. IODebugContext* dbg) override {
  28. IOStatus rv =
  29. target()->PositionedRead(offset, n, options, result, scratch, dbg);
  30. fs_->counters()->reads.RecordOp(rv, result->size());
  31. return rv;
  32. }
  33. };
  34. class CountedRandomAccessFile : public FSRandomAccessFileOwnerWrapper {
  35. private:
  36. CountedFileSystem* fs_;
  37. public:
  38. CountedRandomAccessFile(std::unique_ptr<FSRandomAccessFile>&& f,
  39. CountedFileSystem* fs)
  40. : FSRandomAccessFileOwnerWrapper(std::move(f)), fs_(fs) {}
  41. ~CountedRandomAccessFile() override { fs_->counters()->closes++; }
  42. IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
  43. Slice* result, char* scratch,
  44. IODebugContext* dbg) const override {
  45. IOStatus rv = target()->Read(offset, n, options, result, scratch, dbg);
  46. fs_->counters()->reads.RecordOp(rv, result->size());
  47. return rv;
  48. }
  49. IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
  50. const IOOptions& options, IODebugContext* dbg) override {
  51. IOStatus rv = target()->MultiRead(reqs, num_reqs, options, dbg);
  52. for (size_t r = 0; r < num_reqs; r++) {
  53. fs_->counters()->reads.RecordOp(reqs[r].status, reqs[r].result.size());
  54. }
  55. return rv;
  56. }
  57. };
  58. class CountedWritableFile : public FSWritableFileOwnerWrapper {
  59. private:
  60. CountedFileSystem* fs_;
  61. public:
  62. CountedWritableFile(std::unique_ptr<FSWritableFile>&& f,
  63. CountedFileSystem* fs)
  64. : FSWritableFileOwnerWrapper(std::move(f)), fs_(fs) {}
  65. IOStatus Append(const Slice& data, const IOOptions& options,
  66. IODebugContext* dbg) override {
  67. IOStatus rv = target()->Append(data, options, dbg);
  68. fs_->counters()->writes.RecordOp(rv, data.size());
  69. return rv;
  70. }
  71. IOStatus Append(const Slice& data, const IOOptions& options,
  72. const DataVerificationInfo& info,
  73. IODebugContext* dbg) override {
  74. IOStatus rv = target()->Append(data, options, info, dbg);
  75. fs_->counters()->writes.RecordOp(rv, data.size());
  76. return rv;
  77. }
  78. IOStatus PositionedAppend(const Slice& data, uint64_t offset,
  79. const IOOptions& options,
  80. IODebugContext* dbg) override {
  81. IOStatus rv = target()->PositionedAppend(data, offset, options, dbg);
  82. fs_->counters()->writes.RecordOp(rv, data.size());
  83. return rv;
  84. }
  85. IOStatus PositionedAppend(const Slice& data, uint64_t offset,
  86. const IOOptions& options,
  87. const DataVerificationInfo& info,
  88. IODebugContext* dbg) override {
  89. IOStatus rv = target()->PositionedAppend(data, offset, options, info, dbg);
  90. fs_->counters()->writes.RecordOp(rv, data.size());
  91. return rv;
  92. }
  93. IOStatus Close(const IOOptions& options, IODebugContext* dbg) override {
  94. IOStatus rv = target()->Close(options, dbg);
  95. if (rv.ok()) {
  96. fs_->counters()->closes++;
  97. }
  98. return rv;
  99. }
  100. IOStatus Flush(const IOOptions& options, IODebugContext* dbg) override {
  101. IOStatus rv = target()->Flush(options, dbg);
  102. if (rv.ok()) {
  103. fs_->counters()->flushes++;
  104. }
  105. return rv;
  106. }
  107. IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override {
  108. IOStatus rv = target()->Sync(options, dbg);
  109. if (rv.ok()) {
  110. fs_->counters()->syncs++;
  111. }
  112. return rv;
  113. }
  114. IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override {
  115. IOStatus rv = target()->Fsync(options, dbg);
  116. if (rv.ok()) {
  117. fs_->counters()->fsyncs++;
  118. }
  119. return rv;
  120. }
  121. IOStatus RangeSync(uint64_t offset, uint64_t nbytes, const IOOptions& options,
  122. IODebugContext* dbg) override {
  123. IOStatus rv = target()->RangeSync(offset, nbytes, options, dbg);
  124. if (rv.ok()) {
  125. fs_->counters()->syncs++;
  126. }
  127. return rv;
  128. }
  129. };
  130. class CountedRandomRWFile : public FSRandomRWFileOwnerWrapper {
  131. private:
  132. mutable CountedFileSystem* fs_;
  133. public:
  134. CountedRandomRWFile(std::unique_ptr<FSRandomRWFile>&& f,
  135. CountedFileSystem* fs)
  136. : FSRandomRWFileOwnerWrapper(std::move(f)), fs_(fs) {}
  137. IOStatus Write(uint64_t offset, const Slice& data, const IOOptions& options,
  138. IODebugContext* dbg) override {
  139. IOStatus rv = target()->Write(offset, data, options, dbg);
  140. fs_->counters()->writes.RecordOp(rv, data.size());
  141. return rv;
  142. }
  143. IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
  144. Slice* result, char* scratch,
  145. IODebugContext* dbg) const override {
  146. IOStatus rv = target()->Read(offset, n, options, result, scratch, dbg);
  147. fs_->counters()->reads.RecordOp(rv, result->size());
  148. return rv;
  149. }
  150. IOStatus Flush(const IOOptions& options, IODebugContext* dbg) override {
  151. IOStatus rv = target()->Flush(options, dbg);
  152. if (rv.ok()) {
  153. fs_->counters()->flushes++;
  154. }
  155. return rv;
  156. }
  157. IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override {
  158. IOStatus rv = target()->Sync(options, dbg);
  159. if (rv.ok()) {
  160. fs_->counters()->syncs++;
  161. }
  162. return rv;
  163. }
  164. IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override {
  165. IOStatus rv = target()->Fsync(options, dbg);
  166. if (rv.ok()) {
  167. fs_->counters()->fsyncs++;
  168. }
  169. return rv;
  170. }
  171. IOStatus Close(const IOOptions& options, IODebugContext* dbg) override {
  172. IOStatus rv = target()->Close(options, dbg);
  173. if (rv.ok()) {
  174. fs_->counters()->closes++;
  175. }
  176. return rv;
  177. }
  178. };
  179. class CountedDirectory : public FSDirectoryWrapper {
  180. private:
  181. mutable CountedFileSystem* fs_;
  182. bool closed_ = false;
  183. public:
  184. CountedDirectory(std::unique_ptr<FSDirectory>&& f, CountedFileSystem* fs)
  185. : FSDirectoryWrapper(std::move(f)), fs_(fs) {}
  186. IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override {
  187. IOStatus rv = FSDirectoryWrapper::Fsync(options, dbg);
  188. if (rv.ok()) {
  189. fs_->counters()->dsyncs++;
  190. }
  191. return rv;
  192. }
  193. IOStatus Close(const IOOptions& options, IODebugContext* dbg) override {
  194. IOStatus rv = FSDirectoryWrapper::Close(options, dbg);
  195. if (rv.ok()) {
  196. fs_->counters()->closes++;
  197. fs_->counters()->dir_closes++;
  198. closed_ = true;
  199. }
  200. return rv;
  201. }
  202. IOStatus FsyncWithDirOptions(const IOOptions& options, IODebugContext* dbg,
  203. const DirFsyncOptions& dir_options) override {
  204. IOStatus rv =
  205. FSDirectoryWrapper::FsyncWithDirOptions(options, dbg, dir_options);
  206. if (rv.ok()) {
  207. fs_->counters()->dsyncs++;
  208. }
  209. return rv;
  210. }
  211. ~CountedDirectory() {
  212. if (!closed_) {
  213. // TODO: fix DB+CF code to use explicit Close, not rely on destructor
  214. fs_->counters()->closes++;
  215. fs_->counters()->dir_closes++;
  216. }
  217. }
  218. };
  219. } // anonymous namespace
  220. std::string FileOpCounters::PrintCounters() const {
  221. std::stringstream ss;
  222. ss << "Num files opened: " << opens.load(std::memory_order_relaxed)
  223. << std::endl;
  224. ss << "Num files deleted: " << deletes.load(std::memory_order_relaxed)
  225. << std::endl;
  226. ss << "Num files renamed: " << renames.load(std::memory_order_relaxed)
  227. << std::endl;
  228. ss << "Num Flush(): " << flushes.load(std::memory_order_relaxed) << std::endl;
  229. ss << "Num Sync(): " << syncs.load(std::memory_order_relaxed) << std::endl;
  230. ss << "Num Fsync(): " << fsyncs.load(std::memory_order_relaxed) << std::endl;
  231. ss << "Num Dir Fsync(): " << dsyncs.load(std::memory_order_relaxed)
  232. << std::endl;
  233. ss << "Num Close(): " << closes.load(std::memory_order_relaxed) << std::endl;
  234. ss << "Num Dir Open(): " << dir_opens.load(std::memory_order_relaxed)
  235. << std::endl;
  236. ss << "Num Dir Close(): " << dir_closes.load(std::memory_order_relaxed)
  237. << std::endl;
  238. ss << "Num Read(): " << reads.ops.load(std::memory_order_relaxed)
  239. << std::endl;
  240. ss << "Num Append(): " << writes.ops.load(std::memory_order_relaxed)
  241. << std::endl;
  242. ss << "Num bytes read: " << reads.bytes.load(std::memory_order_relaxed)
  243. << std::endl;
  244. ss << "Num bytes written: " << writes.bytes.load(std::memory_order_relaxed)
  245. << std::endl;
  246. return ss.str();
  247. }
  248. CountedFileSystem::CountedFileSystem(const std::shared_ptr<FileSystem>& base)
  249. : FileSystemWrapper(base) {}
  250. IOStatus CountedFileSystem::NewSequentialFile(
  251. const std::string& f, const FileOptions& options,
  252. std::unique_ptr<FSSequentialFile>* r, IODebugContext* dbg) {
  253. std::unique_ptr<FSSequentialFile> base;
  254. IOStatus s = target()->NewSequentialFile(f, options, &base, dbg);
  255. if (s.ok()) {
  256. counters_.opens++;
  257. r->reset(new CountedSequentialFile(std::move(base), this));
  258. }
  259. return s;
  260. }
  261. IOStatus CountedFileSystem::NewRandomAccessFile(
  262. const std::string& f, const FileOptions& options,
  263. std::unique_ptr<FSRandomAccessFile>* r, IODebugContext* dbg) {
  264. std::unique_ptr<FSRandomAccessFile> base;
  265. IOStatus s = target()->NewRandomAccessFile(f, options, &base, dbg);
  266. if (s.ok()) {
  267. counters_.opens++;
  268. r->reset(new CountedRandomAccessFile(std::move(base), this));
  269. }
  270. return s;
  271. }
  272. IOStatus CountedFileSystem::NewWritableFile(const std::string& f,
  273. const FileOptions& options,
  274. std::unique_ptr<FSWritableFile>* r,
  275. IODebugContext* dbg) {
  276. std::unique_ptr<FSWritableFile> base;
  277. IOStatus s = target()->NewWritableFile(f, options, &base, dbg);
  278. if (s.ok()) {
  279. counters_.opens++;
  280. r->reset(new CountedWritableFile(std::move(base), this));
  281. }
  282. return s;
  283. }
  284. IOStatus CountedFileSystem::ReopenWritableFile(
  285. const std::string& fname, const FileOptions& options,
  286. std::unique_ptr<FSWritableFile>* result, IODebugContext* dbg) {
  287. std::unique_ptr<FSWritableFile> base;
  288. IOStatus s = target()->ReopenWritableFile(fname, options, &base, dbg);
  289. if (s.ok()) {
  290. counters_.opens++;
  291. result->reset(new CountedWritableFile(std::move(base), this));
  292. }
  293. return s;
  294. }
  295. IOStatus CountedFileSystem::ReuseWritableFile(
  296. const std::string& fname, const std::string& old_fname,
  297. const FileOptions& options, std::unique_ptr<FSWritableFile>* result,
  298. IODebugContext* dbg) {
  299. std::unique_ptr<FSWritableFile> base;
  300. IOStatus s =
  301. target()->ReuseWritableFile(fname, old_fname, options, &base, dbg);
  302. if (s.ok()) {
  303. counters_.opens++;
  304. result->reset(new CountedWritableFile(std::move(base), this));
  305. }
  306. return s;
  307. }
  308. IOStatus CountedFileSystem::NewRandomRWFile(
  309. const std::string& name, const FileOptions& options,
  310. std::unique_ptr<FSRandomRWFile>* result, IODebugContext* dbg) {
  311. std::unique_ptr<FSRandomRWFile> base;
  312. IOStatus s = target()->NewRandomRWFile(name, options, &base, dbg);
  313. if (s.ok()) {
  314. counters_.opens++;
  315. result->reset(new CountedRandomRWFile(std::move(base), this));
  316. }
  317. return s;
  318. }
  319. IOStatus CountedFileSystem::NewDirectory(const std::string& name,
  320. const IOOptions& options,
  321. std::unique_ptr<FSDirectory>* result,
  322. IODebugContext* dbg) {
  323. std::unique_ptr<FSDirectory> base;
  324. IOStatus s = target()->NewDirectory(name, options, &base, dbg);
  325. if (s.ok()) {
  326. counters_.opens++;
  327. counters_.dir_opens++;
  328. result->reset(new CountedDirectory(std::move(base), this));
  329. }
  330. return s;
  331. }
  332. } // namespace ROCKSDB_NAMESPACE