From: Joao Eduardo Luis Date: Thu, 22 Aug 2013 15:17:02 +0000 (+0100) Subject: os: KeyValueDB: expose interface to obtain estimated store size X-Git-Tag: v0.69~48^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7a091d3161b34a123547da8a764da051cd60271a;p=ceph.git os: KeyValueDB: expose interface to obtain estimated store size On LevelDBStore, instead of using leveldb's GetApproximateSizes() function, we will instead assess what's the store's raw size from the contents of the store dir (this means .sst's, .log's, etc). The reason behind this approach is that GetApproximateSizes() would expect us to provide a range of keys for which to obtain an approximate size; on the other hand, what we really want is to obtain the size of the store -- not the size of the data (besides, with the compaction issues we've been seeing, we wonder how reliable such approximation would be). Signed-off-by: Joao Eduardo Luis --- diff --git a/src/os/KeyValueDB.h b/src/os/KeyValueDB.h index f62bca996a57..e98463aa763a 100644 --- a/src/os/KeyValueDB.h +++ b/src/os/KeyValueDB.h @@ -165,6 +165,8 @@ public: ); } + virtual uint64_t get_estimated_size(map &extra) = 0; + virtual ~KeyValueDB() {} protected: diff --git a/src/os/LevelDBStore.h b/src/os/LevelDBStore.h index f3809cf34965..356ee59aa278 100644 --- a/src/os/LevelDBStore.h +++ b/src/os/LevelDBStore.h @@ -20,6 +20,12 @@ #include "leveldb/filter_policy.h" #endif +#include +#include "common/errno.h" +#include "common/dout.h" +#include "include/assert.h" +#include "common/Formatter.h" + #include "common/ceph_context.h" class PerfCounters; @@ -300,6 +306,64 @@ public: return limit; } + virtual uint64_t get_estimated_size(map &extra) { + DIR *store_dir = opendir(path.c_str()); + if (!store_dir) { + lderr(cct) << __func__ << " something happened opening the store: " + << cpp_strerror(errno) << dendl; + return 0; + } + + uint64_t total_size = 0; + uint64_t sst_size = 0; + uint64_t log_size = 0; + uint64_t misc_size = 0; + + struct dirent *entry = NULL; + while ((entry = readdir(store_dir)) != NULL) { + string n(entry->d_name); + + if (n == "." || n == "..") + continue; + + string fpath = path + '/' + n; + struct stat s; + int err = stat(fpath.c_str(), &s); + if (err < 0) { + lderr(cct) << __func__ << " error obtaining stats for " << fpath + << ": " << cpp_strerror(errno) << dendl; + goto err; + } + + size_t pos = n.find_last_of('.'); + if (pos == string::npos) { + misc_size += s.st_size; + continue; + } + + string ext = n.substr(pos+1); + if (ext == "sst") { + sst_size += s.st_size; + } else if (ext == "log") { + log_size += s.st_size; + } else { + misc_size += s.st_size; + } + } + + total_size = sst_size + log_size + misc_size; + + extra["sst"] = sst_size; + extra["log"] = log_size; + extra["misc"] = misc_size; + extra["total"] = total_size; + +err: + closedir(store_dir); + return total_size; + } + + protected: WholeSpaceIterator _get_iterator() { return std::tr1::shared_ptr( diff --git a/src/test/ObjectMap/KeyValueDBMemory.h b/src/test/ObjectMap/KeyValueDBMemory.h index 93d0809d4915..5cffce3ef04a 100644 --- a/src/test/ObjectMap/KeyValueDBMemory.h +++ b/src/test/ObjectMap/KeyValueDBMemory.h @@ -126,6 +126,24 @@ public: return static_cast(trans.get())->complete(); } + uint64_t get_estimated_size(map &extras) { + uint64_t total_size = 0; + + for (map,bufferlist>::iterator p = db.begin(); + p != db.end(); ++p) { + string prefix = p->first.first; + bufferlist &bl = p->second; + + uint64_t sz = bl.length(); + total_size += sz; + if (extras.count(prefix) == 0) + extras[prefix] = 0; + extras[prefix] += sz; + } + + return total_size; + } + private: bool exists_prefix(const string &prefix) { std::map,bufferlist>::iterator it;