Add documentation for the fields. Clarify their meaning.
Add 2 new fields that track:
- estimated capacity that store is likely to achieve
- estimated available that reflects how much more user data can be
accomodated
Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
store_statfs_t get_stat() const final {
store_statfs_t st;
st.total = segments.get_total_bytes();
- st.total_raw = st.total;
+ st.est_capacity = st.total;
st.available = segments.get_total_bytes() - stats.used_bytes;
- st.avail_raw = st.available;
+ st.est_available = st.available;
st.allocated = stats.used_bytes;
st.data_stored = stats.used_bytes;
store_statfs_t get_stat() const final {
store_statfs_t st;
st.total = get_total_bytes();
- st.total_raw = st.total;
+ st.est_capacity = st.total;
st.available = get_total_bytes() - get_journal_bytes() - stats.used_bytes;
- st.avail_raw = st.available;
+ st.est_available = st.available;
st.allocated = get_journal_bytes() + stats.used_bytes;
st.data_stored = get_journal_bytes() + stats.used_bytes;
return st;
f->dump_int("total_bytes", osd_sum.statfs.total);
f->dump_int("total_avail_bytes", osd_sum.statfs.available);
f->dump_int("total_used_bytes", osd_sum.statfs.get_used());
- f->dump_int("total_raw_bytes", osd_sum.statfs.total_raw);
- f->dump_int("total_avail_raw_bytes", osd_sum.statfs.get_avail_raw());
f->dump_int("total_used_raw_bytes", osd_sum.statfs.get_used_raw());
f->dump_float("total_used_raw_ratio", osd_sum.statfs.get_used_raw_ratio());
+ f->dump_int("total_estimated_capacity", osd_sum.statfs.est_capacity);
+ f->dump_int("total_estimated_avail_bytes", osd_sum.statfs.est_available);
f->dump_unsigned("num_osds", osd_sum.num_osds);
f->dump_unsigned("num_per_pool_osds", osd_sum.num_per_pool_osds);
f->dump_unsigned("num_per_pool_omap_osds", osd_sum.num_per_pool_omap_osds);
f->dump_int("total_bytes", i.second.statfs.total);
f->dump_int("total_avail_bytes", i.second.statfs.available);
f->dump_int("total_used_bytes", i.second.statfs.get_used());
- f->dump_int("total_raw_bytes", i.second.statfs.total_raw);
- f->dump_int("total_avail_raw_bytes", i.second.statfs.get_avail_raw());
f->dump_int("total_used_raw_bytes", i.second.statfs.get_used_raw());
+ f->dump_int("total_estimated_capacity", i.second.statfs.est_capacity);
+ f->dump_int("total_estimated_avail_bytes", i.second.statfs.est_available);
f->dump_float("total_used_raw_ratio",
i.second.statfs.get_used_raw_ratio());
f->close_section();
tbl.define_column("SIZE", TextTable::RIGHT, TextTable::RIGHT);
tbl.define_column("AVAIL", TextTable::RIGHT, TextTable::RIGHT);
tbl.define_column("USED", TextTable::RIGHT, TextTable::RIGHT);
- tbl.define_column("RAW AVAIL", TextTable::RIGHT, TextTable::RIGHT);
tbl.define_column("RAW USED", TextTable::RIGHT, TextTable::RIGHT);
tbl.define_column("%RAW USED", TextTable::RIGHT, TextTable::RIGHT);
+ tbl.define_column("EST AVAIL", TextTable::RIGHT, TextTable::RIGHT);
for (auto& i : osd_sum_by_class) {
tbl << stringify(byte_u_t(i.second.statfs.total))
<< stringify(byte_u_t(i.second.statfs.available))
<< stringify(byte_u_t(i.second.statfs.get_used()))
- << stringify(byte_u_t(i.second.statfs.get_avail_raw()))
<< stringify(byte_u_t(i.second.statfs.get_used_raw()))
<< percentify(i.second.statfs.get_used_raw_ratio()*100.0)
+ << stringify(byte_u_t(i.second.statfs.est_available))
<< TextTable::endrow;
}
tbl << "TOTAL";
tbl << stringify(byte_u_t(osd_sum.statfs.total))
<< stringify(byte_u_t(osd_sum.statfs.available))
<< stringify(byte_u_t(osd_sum.statfs.get_used()))
- << stringify(byte_u_t(osd_sum.statfs.get_avail_raw()))
<< stringify(byte_u_t(osd_sum.statfs.get_used_raw()))
- << percentify(osd_sum.statfs.get_used_raw_ratio()*100.0)
+ << percentify(osd_sum.statfs.get_used_raw_ratio()*100.0)
+ << stringify(byte_u_t(osd_sum.statfs.est_available))
<< TextTable::endrow;
- *ss << "--- STORAGE ---\n";
+ *ss << "--- RAW STORAGE ---\n";
*ss << tbl;
}
}
buf->internally_reserved = 0;
// include dedicated db, too, if that isn't the shared device.
if (bluefs_layout.shared_bdev != BlueFS::BDEV_DB) {
- buf->total += bluefs->get_block_device_size(BlueFS::BDEV_DB);
+ uint64_t s = bluefs->get_block_device_size(BlueFS::BDEV_DB);
+ buf->total += s;
+ buf->internally_reserved += s;
}
// call any non-omap bluefs space "internal metadata"
buf->internal_metadata =
buf->total += bdev->get_size();
}
buf->available = bfree;
+ // fixme! create algorithm to provide better estimates
+ buf->est_capacity = buf->total;
+ buf->est_available = buf->available;
}
int BlueStore::statfs(struct store_statfs_t *buf,
if (backfill_adjusted) {
dout(20) << __func__ << " backfill adjusted " << new_stat << dendl;
}
- float ratio = ((float)new_stat.statfs.get_used_raw()) / ((float)new_stat.statfs.total);
- dout(5) << __func__ << " ratio:" << ratio << " pratio: " << *pratio << dendl;
- return ratio;
+ return ((float)new_stat.statfs.get_used_raw()) / ((float)new_stat.statfs.total);
}
void OSDService::send_message_osd_cluster(int peer, Message *m, epoch_t from_epoch)
dumped_osds.insert(qi.id);
float reweight = qi.is_bucket() ? -1 : osdmap->get_weightf(qi.id);
int64_t kb = 0, kb_used = 0, kb_used_data = 0, kb_used_omap = 0,
- kb_used_meta = 0, kb_avail = 0, kb_used_raw = 0, kb_avail_raw = 0;
+ kb_used_meta = 0, kb_avail = 0;
double util = 0;
if (get_bucket_utilization(qi.id, &kb, &kb_used, &kb_used_data,
- &kb_used_omap, &kb_used_meta, &kb_avail,
- &kb_used_raw, &kb_avail_raw)) {
- auto kb_raw = kb_used_raw + kb_avail_raw;
- if (kb_raw)
- util = 100.0 * (double)kb_used_raw / (double)kb_raw;
- }
+ &kb_used_omap, &kb_used_meta, &kb_avail))
+ if (kb_used && kb)
+ util = 100.0 * (double)kb_used / (double)kb;
double var = 1.0;
if (average_util)
dump_item(qi, reweight, kb, kb_used,
kb_used_data, kb_used_omap, kb_used_meta,
- kb_avail, util, kb_used_raw, kb_avail_raw,
- var, num_pgs, f);
+ kb_avail, util, var, num_pgs, f);
if (!qi.is_bucket() && reweight > 0) {
if (min_var < 0 || var < min_var)
int64_t kb_used_meta,
int64_t kb_avail,
double& util,
- int64_t kb_used_raw,
- int64_t kb_avail_raw,
double& var,
const size_t num_pgs,
F *f) = 0;
!should_dump(i))
continue;
int64_t kb_i, kb_used_i, kb_used_data_i, kb_used_omap_i, kb_used_meta_i,
- kb_avail_i, kb_used_raw_i, kb_avail_raw_i;
+ kb_avail_i;
if (get_osd_utilization(i, &kb_i, &kb_used_i, &kb_used_data_i,
- &kb_used_omap_i, &kb_used_meta_i, &kb_avail_i,
- &kb_used_raw_i, &kb_avail_raw_i)) {
+ &kb_used_omap_i, &kb_used_meta_i, &kb_avail_i)) {
kb += kb_i;
kb_used += kb_used_i;
}
int64_t* kb_used_data,
int64_t* kb_used_omap,
int64_t* kb_used_meta,
- int64_t* kb_avail,
- int64_t* kb_used_raw,
- int64_t* kb_avail_raw) const {
+ int64_t* kb_avail) const {
const osd_stat_t *p = pgmap.get_osd_stat(id);
if (!p) return false;
*kb = p->statfs.kb();
- *kb_used = p->statfs.kb_used();
+ *kb_used = p->statfs.kb_used_raw();
*kb_used_data = p->statfs.kb_used_data();
*kb_used_omap = p->statfs.kb_used_omap();
*kb_used_meta = p->statfs.kb_used_internal_metadata();
*kb_avail = p->statfs.kb_avail();
- *kb_used_raw = p->statfs.kb_used_raw();
- *kb_avail_raw = p->statfs.kb_avail_raw();
return true;
}
int64_t* kb_used_data,
int64_t* kb_used_omap,
int64_t* kb_used_meta,
- int64_t* kb_avail,
- int64_t* kb_used_raw,
- int64_t* kb_avail_raw
- ) const {
+ int64_t* kb_avail) const {
if (id >= 0) {
if (osdmap->is_out(id) || !should_dump(id)) {
*kb = 0;
*kb_used_omap = 0;
*kb_used_meta = 0;
*kb_avail = 0;
- *kb_used_raw = 0;
- *kb_avail_raw = 0;
return true;
}
return get_osd_utilization(id, kb, kb_used, kb_used_data,
- kb_used_omap, kb_used_meta, kb_avail,
- kb_used_raw, kb_avail_raw);
+ kb_used_omap, kb_used_meta, kb_avail);
}
*kb = 0;
*kb_used_omap = 0;
*kb_used_meta = 0;
*kb_avail = 0;
- *kb_used_raw = 0;
- *kb_avail_raw = 0;
for (int k = osdmap->crush->get_bucket_size(id) - 1; k >= 0; k--) {
int item = osdmap->crush->get_bucket_item(id, k);
int64_t kb_i = 0, kb_used_i = 0, kb_used_data_i = 0,
- kb_used_omap_i = 0, kb_used_meta_i = 0, kb_avail_i = 0,
- kb_used_raw_i = 0, kb_avail_raw_i = 0;
+ kb_used_omap_i = 0, kb_used_meta_i = 0, kb_avail_i = 0;
if (!get_bucket_utilization(item, &kb_i, &kb_used_i,
&kb_used_data_i, &kb_used_omap_i,
- &kb_used_meta_i, &kb_avail_i,
- &kb_used_raw_i, &kb_avail_raw_i))
+ &kb_used_meta_i, &kb_avail_i))
return false;
*kb += kb_i;
*kb_used += kb_used_i;
*kb_used_omap += kb_used_omap_i;
*kb_used_meta += kb_used_meta_i;
*kb_avail += kb_avail_i;
- *kb_used_raw += kb_used_raw_i;
- *kb_avail_raw += kb_avail_raw_i;
}
return true;
}
tbl->define_column("WEIGHT", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("REWEIGHT", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("SIZE", TextTable::LEFT, TextTable::RIGHT);
- tbl->define_column("USE", TextTable::LEFT, TextTable::RIGHT);
+ tbl->define_column("RAW USE", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("DATA", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("OMAP", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("META", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("AVAIL", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("%USE", TextTable::LEFT, TextTable::RIGHT);
- tbl->define_column("RAW USE", TextTable::LEFT, TextTable::RIGHT);
- tbl->define_column("RAW AVAIL", TextTable::LEFT, TextTable::RIGHT);
+ tbl->define_column("EST AVAIL", TextTable::LEFT, TextTable::RIGHT);
+ tbl->define_column("EST CAPAC", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("VAR", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("PGS", TextTable::LEFT, TextTable::RIGHT);
tbl->define_column("STATUS", TextTable::LEFT, TextTable::RIGHT);
<< ""
<< "" << "TOTAL"
<< byte_u_t(sum.statfs.total)
- << byte_u_t(sum.statfs.get_used())
+ << byte_u_t(sum.statfs.get_used_raw())
<< byte_u_t(sum.statfs.allocated)
<< byte_u_t(sum.statfs.omap_allocated)
<< byte_u_t(sum.statfs.internal_metadata)
<< byte_u_t(sum.statfs.available)
<< lowprecision_t(average_util)
- << byte_u_t(sum.statfs.get_used_raw())
- << byte_u_t(sum.statfs.get_avail_raw())
+ << byte_u_t(sum.statfs.est_available)
+ << byte_u_t(sum.statfs.est_capacity)
<< ""
<< TextTable::endrow;
}
int64_t kb_used_meta,
int64_t kb_avail,
double& util,
- int64_t kb_used_raw,
- int64_t kb_avail_raw,
double& var,
const size_t num_pgs,
TextTable *tbl) override {
<< byte_u_t(kb_used_meta << 10)
<< byte_u_t(kb_avail << 10)
<< lowprecision_t(util)
- << byte_u_t(kb_used_raw << 10)
- << byte_u_t(kb_avail_raw << 10)
<< lowprecision_t(var);
if (qi.is_bucket()) {
int64_t kb_used_meta,
int64_t kb_avail,
double& util,
- int64_t kb_used_raw, //FIXME
- int64_t kb_avail_raw,
double& var,
const size_t num_pgs,
Formatter *f) override {
f->dump_int("kb_used_meta", kb_used_meta);
f->dump_int("kb_avail", kb_avail);
f->dump_float("utilization", util);
- f->dump_int("kb_used_raw", kb_used_raw);
- f->dump_int("kb_avail_raw", kb_avail_raw);
f->dump_float("var", var);
f->dump_unsigned("pgs", num_pgs);
if (!qi.is_bucket()) {
auto& s = sum.statfs;
f->dump_int("total_kb", s.kb());
- f->dump_int("total_kb_used", s.kb_used());
+ f->dump_int("total_kb_used", s.kb_used_raw());
f->dump_int("total_kb_used_data", s.kb_used_data());
f->dump_int("total_kb_used_omap", s.kb_used_omap());
f->dump_int("total_kb_used_meta", s.kb_used_internal_metadata());
f->dump_int("total_kb_avail", s.kb_avail());
f->dump_float("average_utilization", average_util);
- f->dump_int("total_kb_used_raw", s.kb_used_raw());
- f->dump_int("total_kb_avail_raw", s.kb_avail_raw());
f->dump_float("min_var", min_var);
f->dump_float("max_var", max_var);
f->dump_float("dev", dev());
} else {
statfs.internally_reserved = 0;
}
- statfs.total_raw = kb << 10;
- statfs.avail_raw = kb_avail << 10;
+ statfs.est_capacity = kb << 10;
+ statfs.est_available = kb_avail << 10;
statfs.allocated = kb_used_data << 10;
statfs.omap_allocated = kb_used_omap << 10;
statfs.internal_metadata = kb_used_meta << 10;
return total == other.total
&& available == other.available
&& internally_reserved == other.internally_reserved
- && total_raw == other.total_raw
- && avail_raw == other.avail_raw
+ && est_capacity == other.est_capacity
+ && est_available == other.est_available
&& allocated == other.allocated
&& data_stored == other.data_stored
&& data_compressed == other.data_compressed
f->dump_int("total", total);
f->dump_int("available", available);
f->dump_int("internally_reserved", internally_reserved);
- f->dump_int("total_raw", total_raw);
- f->dump_int("avail_raw", avail_raw);
+ f->dump_int("total_estimated", est_capacity);
+ f->dump_int("available_estimated", est_available);
f->dump_int("allocated", allocated);
f->dump_int("data_stored", data_stored);
f->dump_int("data_compressed", data_compressed);
encode(internal_metadata, bl);
// since struct_v == 2
- encode(total_raw, bl);
- encode(avail_raw, bl);
+ encode(est_capacity, bl);
+ encode(est_available, bl);
ENCODE_FINISH(bl);
}
void store_statfs_t::decode(ceph::buffer::list::const_iterator &bl)
decode(internal_metadata, bl);
if (struct_v >= 2) {
- decode(total_raw, bl);
- decode(avail_raw, bl);
+ decode(est_capacity, bl);
+ decode(est_available, bl);
} else {
- total_raw = total;
- avail_raw = available;
+ est_capacity = total;
+ est_available = available;
}
DECODE_FINISH(bl);
}
<< "store_statfs(0x" << s.available
<< "/0x" << s.internally_reserved
<< "/0x" << s.total
- << ", raw 0x" << s.avail_raw
- << "/0x" << s.total_raw
+ << ", est 0x" << s.est_available
+ << "/0x" << s.est_capacity
<< ", data 0x" << s.data_stored
<< "/0x" << s.allocated
<< ", compress 0x" << s.data_compressed
a.total = 234;
a.available = 123;
a.internally_reserved = 33;
- a.total_raw = 234;
- a.avail_raw = 123;
+ a.est_capacity = 234;
+ a.est_available = 123;
a.allocated = 32;
a.data_stored = 44;
a.data_compressed = 21;
*/
struct store_statfs_t
{
- uint64_t total = 0; ///< Total logical bytes
- uint64_t available = 0; ///< Free bytes available
- uint64_t internally_reserved = 0; ///< Bytes reserved for internal purposes
-
- // physical bytes
- uint64_t total_raw = 0; ///< Total physical bytes
- uint64_t avail_raw = 0; ///< Physically used bytes
-
- int64_t allocated = 0; ///< Bytes allocated for user data
- int64_t data_stored = 0; ///< Bytes actually stored by the user
- int64_t data_compressed = 0; ///< Bytes stored after compression
- int64_t data_compressed_allocated = 0; ///< Bytes allocated for compressed data
- int64_t data_compressed_original = 0; ///< Bytes that were compressed
-
- int64_t omap_allocated = 0; ///< approx usage of omap data
- int64_t internal_metadata = 0; ///< approx usage of internal metadata
+ // Primary device stats
+ uint64_t total = 0; ///< Total capacity. Store is able to accomodate at least this amount of data.
+ /// For regular devices it is the device size. For block devices that employ
+ /// compression it is the physical capacity, not the logical space size.
+ /// This is the value crush uses for weight.
+ /// BlueStore: If DB volume exists, its size is added here.
+ uint64_t available = 0; ///< Available capacity. Indicates how much more data can fit on the device.
+ /// The value is a minimum should new data be non-compressible 100% entropy.
+ /// If ObjectStore compression is enabled or block device employs hardware
+ /// compression it might accomodate more.
+ uint64_t internally_reserved = 0; ///< Bytes that are part of total but cannot be directly used for storing data.
+ /// BlueStore: if DB volume exists, it is considered reserved.
+ uint64_t est_capacity = 0; ///< Reflects projection of how much user data will fit on the store.
+ /// When full est_capacity and data_stored should be the same.
+ uint64_t est_available = 0; ///< Reflects projection of how much more user data can the store accomodate.
+ /// Typically, data_stored + est_available ~= est_capacity.
+
+ // Additional user-specific ObjectStore stats
+ int64_t allocated = 0; ///< Bytes allocated - how much of logical space is occupied by user data
+ int64_t data_stored = 0; ///< Bytes stored by user - how much data is kept in the store from user's perspective.
+ int64_t data_compressed = 0; ///< Output compressed - how many bytes compression produced.
+ int64_t data_compressed_allocated = 0; ///< Stored compressed - how much logical disk space compressed data occupies.
+ /// Reported in bytes but counts full allocation units.
+ int64_t data_compressed_original = 0; ///< Input data compressed - how many user bytes have undergone compression.
+
+ // Additional internal ObjectStore stats
+ int64_t omap_allocated = 0; ///< Bytes for OMAP - how much space used to keep OMAPs (estimation)
+ int64_t internal_metadata = 0; ///< Bytes for internal metadata - how much space used for internal metadata
+ /// BlueStore: omap_allocated + internal_metadata together reflect RocksDB size.
void reset() {
*this = store_statfs_t();
FLOOR(total);
FLOOR(available);
FLOOR(internally_reserved);
-
- FLOOR(total_raw);
- FLOOR(avail_raw);
+ FLOOR(est_capacity);
+ FLOOR(est_available);
FLOOR(allocated);
FLOOR(data_stored);
return total - available - internally_reserved;
}
- // bytes physically used
+ // this accumulates both actually used and statfs's internally_reserved
uint64_t get_used_raw() const {
- return total_raw - avail_raw;
- }
- // bytes physically available
- uint64_t get_avail_raw() const {
- return avail_raw;
+ return total - available;
}
float get_used_raw_ratio() const {
- if (total_raw) {
- return (float)get_used_raw() / (float)total_raw;
+ if (total) {
+ return (float)get_used_raw() / (float)total;
} else {
return 0.0;
}
return total >> 10;
}
uint64_t kb_used() const {
- return get_used() >> 10;
- }
-
- uint64_t kb_avail_raw() const {
- return avail_raw >> 10;
- }
- uint64_t kb_total_raw() const {
- return total_raw >> 10;
+ return (total - available - internally_reserved) >> 10;
}
uint64_t kb_used_raw() const {
return get_used_raw() >> 10;
total += o.total;
available += o.available;
internally_reserved += o.internally_reserved;
-
- total_raw += o.total_raw;
- avail_raw += o.avail_raw;
+ est_capacity += o.est_capacity;
+ est_available += o.est_available;
allocated += o.allocated;
data_stored += o.data_stored;
data_compressed += o.data_compressed;
data_compressed_allocated += o.data_compressed_allocated;
data_compressed_original += o.data_compressed_original;
+
omap_allocated += o.omap_allocated;
internal_metadata += o.internal_metadata;
}
total -= o.total;
available -= o.available;
internally_reserved -= o.internally_reserved;
-
- total_raw -= o.total_raw;
- avail_raw -= o.avail_raw;
+ est_capacity -= o.est_capacity;
+ est_available -= o.est_available;
allocated -= o.allocated;
data_stored -= o.data_stored;