This option is similar to osd_snap_trim_sleep: simply inject an optional
sleep in the thread that is doing scrub work. This is a very kludgey and
coarse knob for limiting the impact of scrub on the cluster, but can help
until we have a more robust and elegant solution.
Only sleep if we are in the NEW_CHUNK state to avoid delaying processing of
an in-progress chunk. In this state nothing is blocked on anything.
Conveniently, chunky_scrub() requeues itself for each new chunk.
Backport: firefly, dumpling
Signed-off-by: Sage Weil <sage@inktank.com>
OPTION(osd_scrub_max_interval, OPT_FLOAT, 7*60*60*24) // regardless of load
OPTION(osd_scrub_chunk_min, OPT_INT, 5)
OPTION(osd_scrub_chunk_max, OPT_INT, 25)
+OPTION(osd_scrub_sleep, OPT_FLOAT, 0) // sleep between [deep]scrub ops
OPTION(osd_deep_scrub_interval, OPT_FLOAT, 60*60*24*7) // once a week
OPTION(osd_deep_scrub_stride, OPT_INT, 524288)
OPTION(osd_scan_list_ping_tp_interval, OPT_U64, 100)
void PG::scrub(ThreadPool::TPHandle &handle)
{
lock();
+ if (g_conf->osd_scrub_sleep > 0 &&
+ (scrubber.state == PG::Scrubber::NEW_CHUNK ||
+ scrubber.state == PG::Scrubber::INACTIVE)) {
+ dout(20) << __func__ << " state is INACTIVE|NEW_CHUNK, sleeping" << dendl;
+ unlock();
+ utime_t t;
+ t.set_from_double(g_conf->osd_scrub_sleep);
+ t.sleep();
+ lock();
+ dout(20) << __func__ << " slept for " << t << dendl;
+ }
if (deleting) {
unlock();
return;