Skip to content

Commit 72263db

Browse files
committed
os/bluestore: Add health warning for bluestore fragmentation
Changed "bluestore/fragmentation_micros" from quick imprecise to slow but more representative score. Introduced config "bluestore_warn_on_free_fragmentation" that controls when free space fragmentation score becomes a health warning. Currently calculation of fragmentation score might be non-instant for severly fragmented disks. It might induce stalls to write IO. Config value "bluestore_fragmentation_check_period" control score calculation period. In future, costly score calculation will be replaced with method that continously updates score. Signed-off-by: Adam Kupczyk <[email protected]>
1 parent 862ed6e commit 72263db

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

src/common/options/global.yaml.in

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5482,6 +5482,29 @@ options:
54825482
desc: Enable health indication when spurious read errors are observed by OSD
54835483
default: true
54845484
with_legacy: true
5485+
- name: bluestore_warn_on_free_fragmentation
5486+
type: float
5487+
level: basic
5488+
desc: Level at which disk free fragmentation causes health warning. Set "1" to disable.
5489+
This is same value as admin command "bluestore allocator score block".
5490+
default: 0.8
5491+
with_legacy: false
5492+
flags:
5493+
- runtime
5494+
see_also:
5495+
- bluestore_fragmentation_check_period
5496+
- name: bluestore_fragmentation_check_period
5497+
type: uint
5498+
level: basic
5499+
desc: The period to perform bluestore free fragmentation check.
5500+
Checking fragmentation is usually almost immediate. For highly fragmented storage,
5501+
it can take several miliseconds. It can cause a stall to a write operation.
5502+
default: 3600
5503+
with_legacy: false
5504+
flags:
5505+
- runtime
5506+
see_also:
5507+
- bluestore_warn_on_free_fragmentation
54855508
- name: bluestore_slow_ops_warn_lifetime
54865509
type: uint
54875510
level: advanced

src/os/bluestore/BlueStore.cc

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5270,7 +5270,7 @@ void BlueStore::Collection::split_cache(
52705270
// MempoolThread
52715271

52725272
#undef dout_prefix
5273-
#define dout_prefix *_dout << "bluestore.MempoolThread(" << this << ") "
5273+
#define dout_prefix *_dout << "bluestore.MempoolThread "
52745274
#undef dout_context
52755275
#define dout_context store->cct
52765276

@@ -5397,6 +5397,23 @@ void *BlueStore::MempoolThread::entry()
53975397
interval_stats_trim = false;
53985398

53995399
store->refresh_perf_counters();
5400+
uint64_t period = store->cct->_conf.get_val<uint64_t>("bluestore_fragmentation_check_period");
5401+
if (period != 0 && store->alloc) {
5402+
auto now = mono_clock::now();
5403+
timespan elapsed = now - last_fragmentation_check;
5404+
if (elapsed > make_timespan(period)) {
5405+
last_fragmentation_check = now;
5406+
double score;
5407+
score = store->alloc->get_fragmentation_score();
5408+
store->logger->set(l_bluestore_fragmentation, score * 1e6);
5409+
now = mono_clock::now();
5410+
elapsed = now - last_fragmentation_check;
5411+
auto seconds = elapsed.count() * 1e-9;
5412+
dout(0) << std::fixed << std::setprecision(6)
5413+
<< "fragmentation_score=" << score << " took=" << seconds << "s" << dendl;
5414+
}
5415+
}
5416+
54005417
auto wait = ceph::make_timespan(
54015418
store->cct->_conf->bluestore_cache_trim_interval);
54025419
cond.wait_for(l, wait);
@@ -15024,9 +15041,6 @@ void BlueStore::_kv_finalize_thread()
1502415041

1502515042
// this is as good a place as any ...
1502615043
_reap_collections();
15027-
logger->set(l_bluestore_fragmentation,
15028-
(uint64_t)(alloc ? alloc->get_fragmentation() * 1000 : 0));
15029-
1503015044
log_latency("kv_final",
1503115045
l_bluestore_kv_final_lat,
1503215046
mono_clock::now() - start,
@@ -19016,6 +19030,11 @@ void BlueStore::_log_alerts(osd_alert_list_t& alerts)
1901619030
"BLUESTORE_NO_COMPRESSION",
1901719031
s0);
1901819032
}
19033+
if (logger->get(l_bluestore_fragmentation) >
19034+
cct->_conf.get_val<double>("bluestore_warn_on_free_fragmentation") * 1e6) {
19035+
alerts.emplace("BLUESTORE_FREE_FRAGMENTATION",
19036+
fmt::format("{0:.6f}", logger->get(l_bluestore_fragmentation) * 1e-6));
19037+
}
1901919038
}
1902019039

1902119040
void BlueStore::_collect_allocation_stats(uint64_t need, uint32_t alloc_size,

src/os/bluestore/BlueStore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2768,6 +2768,8 @@ class BlueStore : public ObjectStore,
27682768
private:
27692769
void _update_cache_settings();
27702770
void _resize_shards(bool interval_stats);
2771+
2772+
mono_clock::time_point last_fragmentation_check;
27712773
} mempool_thread;
27722774

27732775
#ifdef WITH_BLKIN

0 commit comments

Comments
 (0)