Skip to content

Commit 12fbcab

Browse files
committed
osd/scrub: remove the deep-scrubs deadline attribute
As it is no longer meaningful in the context of the new scrub scheduling design. The change mandates fixes to the way 'schedule-[deeps]crub' commands are implemented. The offset to use when forcing the last-scrub timestamp to a new value in now calculated in ScrubJob::guaranteed_offset(), as ScrubJob is where all schedule adjustments (which employ the same logic) are implemented. Signed-off-by: Ronen Friedman <[email protected]> (cherry picked from commit 4e6323f)
1 parent 00af7eb commit 12fbcab

File tree

3 files changed

+70
-66
lines changed

3 files changed

+70
-66
lines changed

src/osd/scrubber/pg_scrubber.cc

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -687,14 +687,15 @@ Scrub::sched_conf_t PgScrubber::populate_config_params() const
687687
deep_pool > 0.0 ? deep_pool : conf->osd_deep_scrub_interval;
688688

689689
/**
690-
* 'max_deep' and 'max_shallow' are set to the maximum allowed delay between
691-
* scrubs. These deadlines have almost no effect on scrub scheduling
690+
* 'max_shallow' is set to the maximum allowed delay between
691+
* scrubs. This deadline has almost no effect on scrub scheduling
692692
* (the only minor exception: when sorting two scrub jobs that are
693-
* equivalent in all but the deadline).
693+
* equivalent in all but the deadline). It will be removed in
694+
* the next version.
694695
*
695696
* 'max_shallow' is controlled by a pool option and a configuration
696697
* parameter. Note that if the value configured is less than the
697-
* shallow interval, the max_shallow is disabled.
698+
* shallow interval (plus expenses), the max_shallow is disabled.
698699
*/
699700
auto max_shallow = pool_conf.value_or(pool_opts_t::SCRUB_MAX_INTERVAL, 0.0);
700701
if (max_shallow <= 0.0) {
@@ -721,10 +722,6 @@ Scrub::sched_conf_t PgScrubber::populate_config_params() const
721722
}
722723
}
723724

724-
// There are no comparable options for max_deep. We set it here to
725-
// 4X the deep interval, as a reasonable default.
726-
configs.max_deep = 4 * configs.deep_interval;
727-
728725
configs.interval_randomize_ratio = conf->osd_scrub_interval_randomize_ratio;
729726
configs.deep_randomize_ratio =
730727
conf.get_val<double>("osd_deep_scrub_interval_cv");
@@ -762,33 +759,29 @@ void PgScrubber::on_operator_periodic_cmd(
762759
scrub_level_t scrub_level,
763760
int64_t offset)
764761
{
765-
const auto cnf = populate_config_params();
766-
dout(10) << fmt::format(
767-
"{}: {} (cmd offset:{}) conf:{}", __func__,
768-
(scrub_level == scrub_level_t::deep ? "deep" : "shallow"), offset,
769-
cnf)
770-
<< dendl;
771-
772-
// move the relevant time-stamp backwards - enough to trigger a scrub
773-
utime_t stamp = ceph_clock_now();
774-
if (offset > 0) {
775-
stamp -= offset;
762+
// if 'offset' wasn't specified - find a value that guarantees the scrub
763+
// target will appear ready for scrubbing (even after random adjustments)
764+
if (offset == 0) {
765+
const auto cnf = populate_config_params();
766+
offset = m_scrub_job->guaranteed_offset(scrub_level, cnf);
767+
dout(15) << fmt::format(
768+
"{}: {} (calculated offset:{}) conf:{}", __func__,
769+
(scrub_level == scrub_level_t::deep ? "deep" : "shallow"),
770+
offset, cnf)
771+
<< dendl;
776772
} else {
777-
double max_iv =
778-
(scrub_level == scrub_level_t::deep)
779-
? 2 * cnf.max_deep
780-
: (cnf.max_shallow ? *cnf.max_shallow : cnf.shallow_interval);
781-
dout(20) << fmt::format(
782-
"{}: stamp:{:s} ms:{}/{}/{}", __func__, stamp,
783-
(cnf.max_shallow ? "ms+" : "ms-"),
784-
(cnf.max_shallow ? *cnf.max_shallow : -999.99),
785-
cnf.shallow_interval)
773+
dout(15) << fmt::format(
774+
"{}: {} command offset:{}", __func__,
775+
(scrub_level == scrub_level_t::deep ? "deep" : "shallow"),
776+
offset)
786777
<< dendl;
787-
stamp -= max_iv;
788778
}
789-
stamp -= 100.0; // for good measure
779+
// move the relevant time-stamp backwards - enough to trigger a scrub
780+
utime_t stamp = ceph_clock_now();
781+
stamp -= offset; // can't combine with prev line
790782

791-
dout(10) << fmt::format("{}: stamp:{:s} ", __func__, stamp) << dendl;
783+
dout(10) << fmt::format("{}: calculated stamp:{:s}", __func__, stamp)
784+
<< dendl;
792785
asok_response_section(f, true, scrub_level, stamp);
793786

794787
if (scrub_level == scrub_level_t::deep) {

src/osd/scrubber/scrub_job.cc

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,22 @@ void ScrubJob::adjust_shallow_schedule(
146146
}
147147

148148

149+
double ScrubJob::guaranteed_offset(
150+
scrub_level_t s_or_d,
151+
const Scrub::sched_conf_t& app_conf)
152+
{
153+
if (s_or_d == scrub_level_t::deep) {
154+
// use the sdv of the deep scrub distribution, times 3 (3-sigma...)
155+
const double sdv = app_conf.deep_interval * app_conf.deep_randomize_ratio;
156+
// note: the '+10.0' is there just to guarantee inequality if '._ratio' is 0
157+
return app_conf.deep_interval + abs(3 * sdv) + 10.0;
158+
}
159+
160+
// shallow scrub
161+
return app_conf.shallow_interval * (2.0 + app_conf.interval_randomize_ratio);
162+
}
163+
164+
149165
void ScrubJob::operator_forced(scrub_level_t s_or_d, scrub_type_t scrub_type)
150166
{
151167
auto& trgt = get_target(s_or_d);
@@ -237,44 +253,35 @@ void ScrubJob::adjust_deep_schedule(
237253
<< dendl;
238254

239255
auto& dp_times = deep_target.sched_info.schedule; // shorthand
256+
dp_times.deadline = utime_t::max(); // no 'max' for deep scrubs
240257

241258
if (ScrubJob::requires_randomization(deep_target.urgency())) {
242-
utime_t adj_not_before = last_deep;
243259
utime_t adj_target = last_deep;
244-
dp_times.deadline = adj_target;
245260

246261
// add a random delay to the proposed scheduled time
247262
const double sdv = app_conf.deep_interval * app_conf.deep_randomize_ratio;
248263
std::normal_distribution<double> normal_dist{app_conf.deep_interval, sdv};
249-
auto next_delay =
250-
std::clamp(normal_dist(random_gen), app_conf.deep_interval - 2 * sdv,
251-
app_conf.deep_interval + 2 * sdv);
264+
auto next_delay = std::clamp(
265+
normal_dist(random_gen), app_conf.deep_interval - 2 * sdv,
266+
app_conf.deep_interval + 2 * sdv);
252267
adj_target += next_delay;
253268
dout(20) << fmt::format(
254-
"deep scrubbing: next_delay={:.0f} (interval={:.0f}, "
255-
"ratio={:.3f}), adjusted:{:s}",
256-
next_delay, app_conf.deep_interval,
257-
app_conf.deep_randomize_ratio, adj_target)
258-
<< dendl;
259-
260-
dp_times.deadline += app_conf.max_deep;
269+
"deep scrubbing: next_delay={:.0f} (interval={:.0f}, "
270+
"ratio={:.3f}), adjusted:{:s}",
271+
next_delay, app_conf.deep_interval,
272+
app_conf.deep_randomize_ratio, adj_target)
273+
<< dendl;
261274

262-
if (adj_not_before < adj_target) {
263-
adj_not_before = adj_target;
264-
}
265275
dp_times.scheduled_at = adj_target;
266-
dp_times.not_before = adj_not_before;
276+
dp_times.not_before = adj_target;
267277
} else {
268-
// the target time is already set. Make sure to reset the n.b. and
269-
// the (irrelevant) deadline
278+
// the target time is already set. The n.b. is set to same
270279
dp_times.not_before = dp_times.scheduled_at;
271-
dp_times.deadline = utime_t::max();
272280
}
273281

274282
dout(10) << fmt::format(
275-
"adjusted: nb:{:s} target:{:s} deadline:{:s} ({})",
276-
dp_times.not_before, dp_times.scheduled_at, dp_times.deadline,
277-
state_desc())
283+
"adjusted: nb:{:s} target:{:s} ({})", dp_times.not_before,
284+
dp_times.scheduled_at, state_desc())
278285
<< dendl;
279286
}
280287

src/osd/scrubber/scrub_job.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,12 @@ struct sched_conf_t {
3838
double deep_interval{0.0};
3939

4040
/**
41-
* the maximum interval between shallow scrubs, as determined by either the
42-
* OSD or the pool configuration. Empty if no limit is configured.
43-
*/
44-
std::optional<double> max_shallow;
45-
46-
/**
47-
* the maximum interval between deep scrubs, after which the
41+
* the maximum interval between shallow scrubs, after which the
4842
* (info-only) "overdue" field in the scheduler dump is set.
49-
* There is no specific configuration parameter to control the
50-
* deep scrubs max. Instead - we set it to 4 times the average
51-
* interval.
43+
* Determined by either the pool or the cluster configuration.
44+
* Empty if no limit is configured.
5245
*/
53-
double max_deep{std::numeric_limits<double>::max()};
46+
std::optional<double> max_shallow;
5447

5548
/**
5649
* interval_randomize_ratio
@@ -274,6 +267,17 @@ class ScrubJob {
274267
*/
275268
void operator_forced(scrub_level_t s_or_d, scrub_type_t scrub_type);
276269

270+
/**
271+
* calculate a time offset large enough, so that once the relevant
272+
* last-scrub timestamp is forced back by this amount, the PG is
273+
* eligible for a periodic scrub of the specified level.
274+
* Used by the scrubber upon receiving a 'fake a scheduled scrub' request
275+
* from the operator.
276+
*/
277+
double guaranteed_offset(
278+
scrub_level_t s_or_d,
279+
const Scrub::sched_conf_t& app_conf);
280+
277281
void dump(ceph::Formatter* f) const;
278282

279283
bool is_registered() const { return registered; }
@@ -430,9 +434,9 @@ struct formatter<Scrub::sched_conf_t> {
430434
{
431435
return fmt::format_to(
432436
ctx.out(),
433-
"periods:s:{}/{},d:{}/{},iv-ratio:{},deep-rand:{},on-inv:{}",
437+
"periods:s:{}/{},d:{},iv-ratio:{},deep-rand:{},on-inv:{}",
434438
cf.shallow_interval, cf.max_shallow.value_or(-1.0), cf.deep_interval,
435-
cf.max_deep, cf.interval_randomize_ratio, cf.deep_randomize_ratio,
439+
cf.interval_randomize_ratio, cf.deep_randomize_ratio,
436440
cf.mandatory_on_invalid);
437441
}
438442
};

0 commit comments

Comments
 (0)