OPTION(mon_leveldb_compression, OPT_BOOL, false) // monitor's leveldb uses compression
OPTION(mon_leveldb_paranoid, OPT_BOOL, false) // monitor's leveldb paranoid flag
OPTION(mon_leveldb_log, OPT_STR, "")
+OPTION(mon_leveldb_size_warn, OPT_U64, 40*1024*1024*1024) // issue a warning when the monitor's leveldb goes over 40GB (in bytes)
OPTION(paxos_stash_full_interval, OPT_INT, 25) // how often (in commits) to stash a full copy of the PaxosService state
OPTION(paxos_max_join_drift, OPT_INT, 10) // max paxos iterations before we must first sync the monitor stores
OPTION(paxos_propose_interval, OPT_DOUBLE, 1.0) // gather updates for this long before proposing a map update
health_detail = "low disk space!";
}
+ if (stats.store_stats.bytes_total >= g_conf->mon_leveldb_size_warn) {
+ if (health_status > HEALTH_WARN)
+ health_status = HEALTH_WARN;
+ if (!health_detail.empty())
+ health_detail.append("; ");
+ stringstream ss;
+ ss << "store is getting too big! "
+ << prettybyte_t(stats.store_stats.bytes_total)
+ << " >= " << prettybyte_t(g_conf->mon_leveldb_size_warn);
+ health_detail.append(ss.str());
+ }
+
if (overall_status > health_status)
overall_status = health_status;
if (f) {
f->open_object_section("mon");
f->dump_string("name", mon_name.c_str());
+ f->open_object_section("data_stats");
stats.dump(f);
+ f->close_section();
f->dump_stream("health") << health_status;
if (health_status != HEALTH_OK)
f->dump_string("health_detail", health_detail);
return overall_status;
}
+int DataHealthService::update_store_stats(DataStats &ours)
+{
+ map<string,uint64_t> extra;
+ uint64_t store_size = mon->store->get_estimated_size(extra);
+ assert(store_size > 0);
+
+ ours.store_stats.bytes_total = store_size;
+ ours.store_stats.bytes_sst = extra["sst"];
+ ours.store_stats.bytes_log = extra["log"];
+ ours.store_stats.bytes_misc = extra["misc"];
+ ours.last_update = ceph_clock_now(g_ceph_context);
+
+ return 0;
+}
+
+
int DataHealthService::update_stats()
{
struct statfs stbuf;
<< " total " << ours.kb_total << " used " << ours.kb_used << " avail " << ours.kb_avail
<< dendl;
ours.last_update = ceph_clock_now(g_ceph_context);
- return 0;
+
+ return update_store_stats(ours);
}
void DataHealthService::share_stats()
#define CEPH_MON_ONDISK_MAGIC "ceph mon volume v012"
+/**
+ * leveldb store stats
+ *
+ * If we ever decide to support multiple backends for the monitor store,
+ * we should then create an abstract class 'MonitorStoreStats' of sorts
+ * and inherit it on LevelDBStoreStats. I'm sure you'll figure something
+ * out.
+ */
+struct LevelDBStoreStats {
+ uint64_t bytes_total;
+ uint64_t bytes_sst;
+ uint64_t bytes_log;
+ uint64_t bytes_misc;
+ utime_t last_update;
+
+ void dump(Formatter *f) const {
+ assert(f != NULL);
+ f->dump_int("bytes_total", bytes_total);
+ f->dump_int("bytes_sst", bytes_sst);
+ f->dump_int("bytes_log", bytes_log);
+ f->dump_int("bytes_misc", bytes_misc);
+ f->dump_stream("last_updated") << last_update;
+ }
+
+ void encode(bufferlist &bl) const {
+ ENCODE_START(1, 1, bl);
+ ::encode(bytes_total, bl);
+ ::encode(bytes_sst, bl);
+ ::encode(bytes_log, bl);
+ ::encode(bytes_misc, bl);
+ ::encode(last_update, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::iterator &p) {
+ DECODE_START(1, p);
+ ::decode(bytes_total, p);
+ ::decode(bytes_sst, p);
+ ::decode(bytes_log, p);
+ ::decode(bytes_misc, p);
+ ::decode(last_update, p);
+ DECODE_FINISH(p);
+ }
+};
+WRITE_CLASS_ENCODER(LevelDBStoreStats);
+
// data stats
struct DataStats {
int latest_avail_percent;
utime_t last_update;
+ LevelDBStoreStats store_stats;
+
void dump(Formatter *f) const {
assert(f != NULL);
- f->open_object_section("data_stats");
f->dump_int("kb_total", kb_total);
f->dump_int("kb_used", kb_used);
f->dump_int("kb_avail", kb_avail);
f->dump_int("avail_percent", latest_avail_percent);
f->dump_stream("last_updated") << last_update;
+ f->open_object_section("store_stats");
+ store_stats.dump(f);
f->close_section();
}
void encode(bufferlist &bl) const {
- ENCODE_START(1, 1, bl);
+ ENCODE_START(2, 1, bl);
::encode(kb_total, bl);
::encode(kb_used, bl);
::encode(kb_avail, bl);
::encode(latest_avail_percent, bl);
::encode(last_update, bl);
+ ::encode(store_stats, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator &p) {
::decode(kb_avail, p);
::decode(latest_avail_percent, p);
::decode(last_update, p);
+ if (struct_v > 1)
+ ::decode(store_stats, p);
+
DECODE_FINISH(p);
}
};