Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nautilus: bluestore: add slow op detection for collection_listing #29227

Merged
merged 4 commits into from Jul 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/common/legacy_config_opts.h
Expand Up @@ -1076,6 +1076,7 @@ OPTION(bluestore_warn_on_bluefs_spillover, OPT_BOOL)
OPTION(bluestore_warn_on_legacy_statfs, OPT_BOOL)
OPTION(bluestore_log_op_age, OPT_DOUBLE)
OPTION(bluestore_log_omap_iterator_age, OPT_DOUBLE)
OPTION(bluestore_log_collection_list_age, OPT_DOUBLE)

OPTION(kstore_max_ops, OPT_U64)
OPTION(kstore_max_bytes, OPT_U64)
Expand Down
6 changes: 5 additions & 1 deletion src/common/options.cc
Expand Up @@ -4827,9 +4827,13 @@ std::vector<Option> get_global_options() {
.set_description("log operation if it's slower than this age (seconds)"),

Option("bluestore_log_omap_iterator_age", Option::TYPE_FLOAT, Option::LEVEL_ADVANCED)
.set_default(1)
.set_default(5)
.set_description("log omap iteration operation if it's slower than this age (seconds)"),

Option("bluestore_log_collection_list_age", Option::TYPE_FLOAT, Option::LEVEL_ADVANCED)
.set_default(60)
.set_description("log collection list operation if it's slower than this age (seconds)"),

// -----------------------------------------
// kstore

Expand Down
180 changes: 117 additions & 63 deletions src/os/bluestore/BlueStore.cc
Expand Up @@ -130,34 +130,6 @@ const string BLUESTORE_GLOBAL_STATFS_KEY = "bluestore_statfs";
*/
#define EXTENT_SHARD_KEY_SUFFIX 'x'

// FIXME minor: make a BlueStore method once we have effecient way to
// map idx to counter nickname
#define LOG_LATENCY_I(logger, cct, idx, v, info) { \
ceph::timespan lat = v; \
logger->tinc(idx, lat); \
if (cct->_conf->bluestore_log_op_age > 0.0 && \
lat >= make_timespan(cct->_conf->bluestore_log_op_age)) { \
dout(0) << __func__ << " slow operation observed for " #idx \
<< ", latency = " << lat \
<< info \
<< dendl; \
} \
}

#define LOG_LATENCY_FN(logger, cct, idx, v, fn) { \
ceph::timespan lat = v; \
logger->tinc(idx, lat); \
if (cct->_conf->bluestore_log_op_age > 0.0 && \
lat >= make_timespan(cct->_conf->bluestore_log_op_age)) { \
dout(0) << __func__ << " slow operation observed for " #idx \
<< ", latency = " << lat \
<< fn(lat) \
<< dendl; \
} \
}

#define LOG_LATENCY(logger, cct, idx, v) LOG_LATENCY_I(logger, cct, idx, v, "")

/*
* string encoding in the key
*
Expand Down Expand Up @@ -3880,13 +3852,11 @@ int BlueStore::OmapIteratorImpl::seek_to_first()
} else {
it = KeyValueDB::Iterator();
}
c->store->log_latency_fn(
c->store->log_latency(
__func__,
l_bluestore_omap_seek_to_first_lat,
mono_clock::now() - start1,
[&] (const ceph::timespan& lat) {
return ", lat = " + timespan_str(lat) + _stringify();
}
);
c->store->cct->_conf->bluestore_log_omap_iterator_age);

return 0;
}
Expand All @@ -3905,10 +3875,12 @@ int BlueStore::OmapIteratorImpl::upper_bound(const string& after)
it = KeyValueDB::Iterator();
}
c->store->log_latency_fn(
__func__,
l_bluestore_omap_upper_bound_lat,
mono_clock::now() - start1,
c->store->cct->_conf->bluestore_log_omap_iterator_age,
[&] (const ceph::timespan& lat) {
return ", after = " + after + ", lat = " + timespan_str(lat) +
return ", after = " + after +
_stringify();
}
);
Expand All @@ -3929,10 +3901,12 @@ int BlueStore::OmapIteratorImpl::lower_bound(const string& to)
it = KeyValueDB::Iterator();
}
c->store->log_latency_fn(
__func__,
l_bluestore_omap_lower_bound_lat,
mono_clock::now() - start1,
c->store->cct->_conf->bluestore_log_omap_iterator_age,
[&] (const ceph::timespan& lat) {
return ", to = " + to + ", lat = " + timespan_str(lat) +
return ", to = " + to +
_stringify();
}
);
Expand Down Expand Up @@ -3961,13 +3935,11 @@ int BlueStore::OmapIteratorImpl::next()
it->next();
r = 0;
}
c->store->log_latency_fn(
c->store->log_latency(
__func__,
l_bluestore_omap_next_lat,
mono_clock::now() - start1,
[&] (const ceph::timespan& lat) {
return ", lat = " + timespan_str(lat) + _stringify();
}
);
c->store->cct->_conf->bluestore_log_omap_iterator_age);

return r;
}
Expand All @@ -3979,6 +3951,7 @@ string BlueStore::OmapIteratorImpl::key()
string db_key = it->raw_key().second;
string user_key;
decode_omap_key(db_key, &user_key);

return user_key;
}

Expand Down Expand Up @@ -4541,6 +4514,8 @@ void BlueStore::_init_logger()
"Average omap iterator lower_bound call latency");
b.add_time_avg(l_bluestore_omap_next_lat, "omap_next_lat",
"Average omap iterator next call latency");
b.add_time_avg(l_bluestore_clist_lat, "clist_lat",
"Average collection listing latency");
logger = b.create_perf_counters();
cct->get_perfcounters_collection()->add(logger);
}
Expand Down Expand Up @@ -8486,7 +8461,10 @@ int BlueStore::read(
RWLock::RLocker l(c->lock);
auto start1 = mono_clock::now();
OnodeRef o = c->get_onode(oid, false);
LOG_LATENCY(logger, cct, l_bluestore_read_onode_meta_lat, mono_clock::now() - start1);
log_latency("get_onode@read",
l_bluestore_read_onode_meta_lat,
mono_clock::now() - start1,
cct->_conf->bluestore_log_op_age);
if (!o || !o->exists) {
r = -ENOENT;
goto out;
Expand Down Expand Up @@ -8515,7 +8493,10 @@ int BlueStore::read(
dout(10) << __func__ << " " << cid << " " << oid
<< " 0x" << std::hex << offset << "~" << length << std::dec
<< " = " << r << dendl;
LOG_LATENCY(logger, cct, l_bluestore_read_lat, mono_clock::now() - start);
log_latency(__func__,
l_bluestore_read_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age);
return r;
}

Expand Down Expand Up @@ -8607,7 +8588,10 @@ int BlueStore::_do_read(

auto start = mono_clock::now();
o->extent_map.fault_range(db, offset, length);
LOG_LATENCY(logger, cct, l_bluestore_read_onode_meta_lat, mono_clock::now() - start);
log_latency(__func__,
l_bluestore_read_onode_meta_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age);
_dump_onode<30>(cct, *o);

ready_regions_t ready_regions;
Expand Down Expand Up @@ -8802,8 +8786,10 @@ int BlueStore::_do_read(
return -EIO;
}
}
LOG_LATENCY_FN(logger, cct, l_bluestore_read_wait_aio_lat,
log_latency_fn(__func__,
l_bluestore_read_wait_aio_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age,
[&](auto lat) { return ", num_ios = " + stringify(num_ios); }
);

Expand Down Expand Up @@ -8951,7 +8937,10 @@ int BlueStore::_verify_csum(OnodeRef& o,
derr << __func__ << " failed with exit code: " << cpp_strerror(r) << dendl;
}
}
LOG_LATENCY(logger, cct, l_bluestore_csum_lat, mono_clock::now() - start);
log_latency(__func__,
l_bluestore_csum_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age);
if (cct->_conf->bluestore_ignore_data_csum) {
return 0;
}
Expand Down Expand Up @@ -8986,7 +8975,10 @@ int BlueStore::_decompress(bufferlist& source, bufferlist* result)
r = -EIO;
}
}
LOG_LATENCY(logger, cct, l_bluestore_decompress_lat, mono_clock::now() - start);
log_latency(__func__,
l_bluestore_decompress_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age);
return r;
}

Expand Down Expand Up @@ -9237,6 +9229,7 @@ int BlueStore::_collection_list(
if (!c->exists)
return -ENOENT;

auto start_time = mono_clock::now();
int r = 0;
ghobject_t static_next;
KeyValueDB::Iterator it;
Expand Down Expand Up @@ -9336,7 +9329,20 @@ int BlueStore::_collection_list(
if (!set_next) {
*pnext = ghobject_t::get_max();
}

log_latency_fn(
__func__,
l_bluestore_clist_lat,
mono_clock::now() - start_time,
cct->_conf->bluestore_log_collection_list_age,
[&] (const ceph::timespan& lat) {
ostringstream ostr;
ostr << ", lat = " << timespan_str(lat)
<< " cid =" << c->cid
<< " start " << start << " end " << end
<< " max " << max;
return ostr.str();
}
);
return r;
}

Expand Down Expand Up @@ -10141,12 +10147,14 @@ void BlueStore::_txc_committed_kv(TransContext *txc)
}
}
txc->log_state_latency(logger, l_bluestore_state_kv_committing_lat);
LOG_LATENCY_FN(logger, cct,
l_bluestore_commit_lat,
ceph::make_timespan(ceph_clock_now() - txc->start),
[&](auto lat) {
return ", txc = " + stringify(txc);
}
log_latency_fn(
__func__,
l_bluestore_commit_lat,
ceph::make_timespan(ceph_clock_now() - txc->start),
cct->_conf->bluestore_log_op_age,
[&](auto lat) {
return ", txc = " + stringify(txc);
}
);
}

Expand Down Expand Up @@ -10652,9 +10660,18 @@ void BlueStore::_kv_sync_thread()
<< " in " << dur
<< " (" << dur_flush << " flush + " << dur_kv << " kv commit)"
<< dendl;
LOG_LATENCY(logger, cct, l_bluestore_kv_flush_lat, dur_flush);
LOG_LATENCY(logger, cct, l_bluestore_kv_commit_lat, dur_kv);
LOG_LATENCY(logger, cct, l_bluestore_kv_sync_lat, dur);
log_latency("kv_flush",
l_bluestore_kv_flush_lat,
dur_flush,
cct->_conf->bluestore_log_op_age);
log_latency("kv_commit",
l_bluestore_kv_commit_lat,
dur_kv,
cct->_conf->bluestore_log_op_age);
log_latency("kv_sync",
l_bluestore_kv_sync_lat,
dur,
cct->_conf->bluestore_log_op_age);
}

if (bluefs) {
Expand Down Expand Up @@ -10748,7 +10765,10 @@ void BlueStore::_kv_finalize_thread()
logger->set(l_bluestore_fragmentation,
(uint64_t)(alloc->get_fragmentation(min_alloc_size) * 1000));

LOG_LATENCY(logger, cct, l_bluestore_kv_final_lat, mono_clock::now() - start);
log_latency("kv_final",
l_bluestore_kv_final_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age);

l.lock();
}
Expand Down Expand Up @@ -11076,8 +11096,14 @@ int BlueStore::queue_transactions(
}
}

LOG_LATENCY(logger, cct, l_bluestore_submit_lat, mono_clock::now() - start);
LOG_LATENCY(logger, cct, l_bluestore_throttle_lat, tend - tstart);
log_latency("submit_transact",
l_bluestore_submit_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age);
log_latency("throttle_transact",
l_bluestore_throttle_lat,
tend - tstart,
cct->_conf->bluestore_log_op_age);
return 0;
}

Expand Down Expand Up @@ -12078,8 +12104,10 @@ int BlueStore::_do_alloc_write(
logger->inc(l_bluestore_compress_rejected_count);
need += wi.blob_length;
}
LOG_LATENCY(logger, cct, l_bluestore_compress_lat,
mono_clock::now() - start);
log_latency("compress@_do_alloc_write",
l_bluestore_compress_lat,
mono_clock::now() - start,
cct->_conf->bluestore_log_op_age );
} else {
need += wi.blob_length;
}
Expand Down Expand Up @@ -13545,12 +13573,38 @@ int BlueStore::_merge_collection(
return r;
}

void BlueStore::log_latency(
const char* name,
int idx,
const ceph::timespan& l,
double lat_threshold,
const char* info) const
{
logger->tinc(idx, l);
if (lat_threshold > 0.0 &&
l >= make_timespan(lat_threshold)) {
dout(0) << __func__ << " slow operation observed for " << name
<< ", latency = " << l
<< info
<< dendl;
}
}

void BlueStore::log_latency_fn(
const char* name,
int idx,
const ceph::timespan& l,
std::function<string (const ceph::timespan& lat)> fn)
double lat_threshold,
std::function<string (const ceph::timespan& lat)> fn) const
{
LOG_LATENCY_FN(logger, cct, idx, l, fn);
logger->tinc(idx, l);
if (lat_threshold > 0.0 &&
l >= make_timespan(lat_threshold)) {
dout(0) << __func__ << " slow operation observed for " << name
<< ", latency = " << l
<< fn(l)
<< dendl;
}
}


Expand Down
15 changes: 12 additions & 3 deletions src/os/bluestore/BlueStore.h
Expand Up @@ -127,6 +127,7 @@ enum {
l_bluestore_omap_upper_bound_lat,
l_bluestore_omap_lower_bound_lat,
l_bluestore_omap_next_lat,
l_bluestore_clist_lat,
l_bluestore_last
};

Expand Down Expand Up @@ -2669,9 +2670,17 @@ class BlueStore : public ObjectStore,
uint64_t size,
PExtentVector* extents);

void log_latency_fn(int idx,
const ceph::timespan& lat,
std::function<string (const ceph::timespan& lat)> fn);
inline void log_latency(const char* name,
int idx,
const ceph::timespan& lat,
double lat_threshold,
const char* info = "") const;

inline void log_latency_fn(const char* name,
int idx,
const ceph::timespan& lat,
double lat_threshold,
std::function<string (const ceph::timespan& lat)> fn) const;

private:
bool _debug_data_eio(const ghobject_t& o) {
Expand Down