Skip to content

Commit 264f186

Browse files
authored
Merge pull request ceph#63263 from ronen-fr/wip-rf-63183-tentacle
tentacle: osd/scrub: remove (was: fix) deadline calculations Reviewed-by: Samuel Just <[email protected]>
2 parents 029a9d7 + 16fe794 commit 264f186

File tree

8 files changed

+106
-169
lines changed

8 files changed

+106
-169
lines changed

doc/rados/operations/pools.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ You may set values for the following keys:
551551

552552
.. describe:: scrub_min_interval
553553

554-
:Description: Sets the minimum interval (in seconds) between successive shallow / light scrubs of the pool's PGs when the load is low. If the default value of ``0`` is in effect, then the value of ``osd_scrub_min_interval`` from central config is used.
554+
:Description: Sets the minimum interval (in seconds) between successive shallow (light) scrubs of the pool's PGs. If this pool attribute is unchanged from its default (``0``), the value of ``osd_scrub_min_interval`` from central config is used instead.
555555

556556
:Type: Double
557557
:Default: ``0``
@@ -560,7 +560,7 @@ You may set values for the following keys:
560560

561561
.. describe:: scrub_max_interval
562562

563-
:Description: Sets the maximum interval (in seconds) between successive shallow / light scrubs of the pool's PGs regardless of cluster load. If the value of ``scrub_max_interval`` is ``0``, then the value ``osd_scrub_max_interval`` from central config is used.
563+
:Description: Sets the maximum interval (in seconds) between successive shallow (light) scrubs of the pool's PGs. Affects the 'overdue' attribute appearing in scrub scheduler dumps. If unchanged from its default of ``0``, the value of ``osd_scrub_max_interval`` from central config is used instead.
564564

565565
:Type: Double
566566
:Default: ``0``
@@ -569,7 +569,7 @@ You may set values for the following keys:
569569

570570
.. describe:: deep_scrub_interval
571571

572-
:Description: Sets the interval (in seconds) for successive pool deep scrubs of the pool's PGs. If the value of ``deep_scrub_interval`` is ``0``, the value ``osd_deep_scrub_interval`` from central config is used.
572+
:Description: Sets the interval (in seconds) for successive pool deep scrubs of the pool's PGs. If unchanged from its default of ``0``, the value of ``osd_deep_scrub_interval`` from central config is used instead.
573573

574574
:Type: Double
575575
:Default: ``0``

qa/standalone/scrub/osd-scrub-test.sh

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,11 @@ DATEFORMAT="%Y-%m-%d"
131131
function check_dump_scrubs() {
132132
local primary=$1
133133
local sched_time_check="$2"
134-
local deadline_check="$3"
135134

136135
DS="$(CEPH_ARGS='' ceph --admin-daemon $(get_asok_path osd.${primary}) dump_scrubs)"
137136
# use eval to drop double-quotes
138137
eval SCHED_TIME=$(echo $DS | jq '.[0].sched_time')
139138
test $(echo $SCHED_TIME | sed $DATESED) = $(date +${DATEFORMAT} -d "now + $sched_time_check") || return 1
140-
# use eval to drop double-quotes
141-
eval DEADLINE=$(echo $DS | jq '.[0].deadline')
142-
test $(echo $DEADLINE | sed $DATESED) = $(date +${DATEFORMAT} -d "now + $deadline_check") || return 1
143139
}
144140

145141
function TEST_interval_changes() {
@@ -178,27 +174,27 @@ function TEST_interval_changes() {
178174
local primary=$(get_primary $poolname obj1)
179175

180176
# Check initial settings from above (min 1 day, min 1 week)
181-
check_dump_scrubs $primary "1 day" "1 week" || return 1
177+
check_dump_scrubs $primary "1 day" || return 1
182178

183179
# Change global osd_scrub_min_interval to 2 days
184180
CEPH_ARGS='' ceph --admin-daemon $(get_asok_path osd.${primary}) config set osd_scrub_min_interval $(expr $day \* 2)
185181
sleep $WAIT_FOR_UPDATE
186-
check_dump_scrubs $primary "2 days" "1 week" || return 1
182+
check_dump_scrubs $primary "2 days" || return 1
187183

188184
# Change global osd_scrub_max_interval to 2 weeks
189185
CEPH_ARGS='' ceph --admin-daemon $(get_asok_path osd.${primary}) config set osd_scrub_max_interval $(expr $week \* 2)
190186
sleep $WAIT_FOR_UPDATE
191-
check_dump_scrubs $primary "2 days" "2 week" || return 1
187+
check_dump_scrubs $primary "2 days" || return 1
192188

193189
# Change pool osd_scrub_min_interval to 3 days
194190
ceph osd pool set $poolname scrub_min_interval $(expr $day \* 3)
195191
sleep $WAIT_FOR_UPDATE
196-
check_dump_scrubs $primary "3 days" "2 week" || return 1
192+
check_dump_scrubs $primary "3 days" || return 1
197193

198194
# Change pool osd_scrub_max_interval to 3 weeks
199195
ceph osd pool set $poolname scrub_max_interval $(expr $week \* 3)
200196
sleep $WAIT_FOR_UPDATE
201-
check_dump_scrubs $primary "3 days" "3 week" || return 1
197+
check_dump_scrubs $primary "3 days" || return 1
202198
perf_counters $dir $OSDS
203199
}
204200

src/osd/scrubber/osd_scrub_sched.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ void ScrubQueue::dump_scrubs(ceph::Formatter* f) const
157157
f->dump_stream("pgid") << e.pgid;
158158
f->dump_stream("sched_time") << e.schedule.not_before;
159159
f->dump_stream("orig_sched_time") << e.schedule.scheduled_at;
160-
f->dump_stream("deadline") << e.schedule.deadline;
161160
f->dump_bool(
162161
"forced",
163162
e.schedule.scheduled_at == PgScrubber::scrub_must_stamp());
@@ -167,7 +166,6 @@ void ScrubQueue::dump_scrubs(ceph::Formatter* f) const
167166
: "deep");
168167
f->dump_stream("urgency") << fmt::format("{}", e.urgency);
169168
f->dump_bool("eligible", e.schedule.not_before <= query_time);
170-
f->dump_bool("overdue", e.schedule.deadline < query_time);
171169
f->dump_stream("last_issue") << fmt::format("{}", e.last_issue);
172170
},
173171
std::numeric_limits<int>::max());

src/osd/scrubber/pg_scrubber.cc

Lines changed: 37 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -674,46 +674,29 @@ Scrub::sched_conf_t PgScrubber::populate_config_params() const
674674
const auto& conf = get_pg_cct()->_conf; // for brevity
675675
Scrub::sched_conf_t configs;
676676

677-
// deep-scrub optimal interval
678-
configs.deep_interval =
679-
pool_conf.value_or(pool_opts_t::DEEP_SCRUB_INTERVAL, 0.0);
680-
if (configs.deep_interval <= 0.0) {
681-
configs.deep_interval = conf->osd_deep_scrub_interval;
682-
}
683-
684-
// shallow-scrub interval
685-
configs.shallow_interval =
677+
// shallow scrubs interval
678+
const auto shallow_pool =
686679
pool_conf.value_or(pool_opts_t::SCRUB_MIN_INTERVAL, 0.0);
687-
if (configs.shallow_interval <= 0.0) {
688-
configs.shallow_interval = conf->osd_scrub_min_interval;
689-
}
690-
691-
// the max allowed delay between scrubs.
692-
// For deep scrubs - there is no equivalent of scrub_max_interval. Per the
693-
// documentation, once deep_scrub_interval has passed, we are already
694-
// "overdue", at least as far as the "ignore allowed load" window is
695-
// concerned.
696-
697-
configs.max_deep = configs.deep_interval + configs.shallow_interval;
698-
699-
auto max_shallow = pool_conf.value_or(pool_opts_t::SCRUB_MAX_INTERVAL, 0.0);
700-
if (max_shallow <= 0.0) {
701-
max_shallow = conf->osd_scrub_max_interval;
702-
}
703-
if (max_shallow > 0.0) {
704-
configs.max_shallow = max_shallow;
705-
// otherwise - we're left with the default nullopt
706-
}
680+
configs.shallow_interval =
681+
shallow_pool > 0.0 ? shallow_pool : conf->osd_scrub_min_interval;
707682

708-
// but seems like our tests require: \todo fix!
709-
configs.max_deep =
710-
std::max(configs.max_shallow.value_or(0.0), configs.deep_interval);
683+
// deep scrubs optimal interval
684+
const auto deep_pool =
685+
pool_conf.value_or(pool_opts_t::DEEP_SCRUB_INTERVAL, 0.0);
686+
configs.deep_interval =
687+
deep_pool > 0.0 ? deep_pool : conf->osd_deep_scrub_interval;
711688

712689
configs.interval_randomize_ratio = conf->osd_scrub_interval_randomize_ratio;
713-
configs.deep_randomize_ratio = conf.get_val<double>("osd_deep_scrub_interval_cv");
690+
configs.deep_randomize_ratio =
691+
conf.get_val<double>("osd_deep_scrub_interval_cv");
714692
configs.mandatory_on_invalid = conf->osd_scrub_invalid_stats;
715693

716-
dout(15) << fmt::format("{}: updated config:{}", __func__, configs) << dendl;
694+
dout(15) << fmt::format(
695+
"{}: inputs: intervals: sh:{}(pl:{}),dp:{}(pl:{})",
696+
__func__, configs.shallow_interval, shallow_pool,
697+
configs.deep_interval, deep_pool)
698+
<< dendl;
699+
dout(10) << fmt::format("{}: updated config:{}", __func__, configs) << dendl;
717700
return configs;
718701
}
719702

@@ -740,33 +723,29 @@ void PgScrubber::on_operator_periodic_cmd(
740723
scrub_level_t scrub_level,
741724
int64_t offset)
742725
{
743-
const auto cnf = populate_config_params();
744-
dout(10) << fmt::format(
745-
"{}: {} (cmd offset:{}) conf:{}", __func__,
746-
(scrub_level == scrub_level_t::deep ? "deep" : "shallow"), offset,
747-
cnf)
748-
<< dendl;
749-
750-
// move the relevant time-stamp backwards - enough to trigger a scrub
751-
utime_t stamp = ceph_clock_now();
752-
if (offset > 0) {
753-
stamp -= offset;
726+
// if 'offset' wasn't specified - find a value that guarantees the scrub
727+
// target will appear ready for scrubbing (even after random adjustments)
728+
if (offset == 0) {
729+
const auto cnf = populate_config_params();
730+
offset = m_scrub_job->guaranteed_offset(scrub_level, cnf);
731+
dout(15) << fmt::format(
732+
"{}: {} (calculated offset:{}) conf:{}", __func__,
733+
(scrub_level == scrub_level_t::deep ? "deep" : "shallow"),
734+
offset, cnf)
735+
<< dendl;
754736
} else {
755-
double max_iv =
756-
(scrub_level == scrub_level_t::deep)
757-
? 2 * cnf.max_deep
758-
: (cnf.max_shallow ? *cnf.max_shallow : cnf.shallow_interval);
759-
dout(20) << fmt::format(
760-
"{}: stamp:{:s} ms:{}/{}/{}", __func__, stamp,
761-
(cnf.max_shallow ? "ms+" : "ms-"),
762-
(cnf.max_shallow ? *cnf.max_shallow : -999.99),
763-
cnf.shallow_interval)
737+
dout(15) << fmt::format(
738+
"{}: {} command offset:{}", __func__,
739+
(scrub_level == scrub_level_t::deep ? "deep" : "shallow"),
740+
offset)
764741
<< dendl;
765-
stamp -= max_iv;
766742
}
767-
stamp -= 100.0; // for good measure
743+
// move the relevant time-stamp backwards - enough to trigger a scrub
744+
utime_t stamp = ceph_clock_now();
745+
stamp -= offset; // can't combine with prev line
768746

769-
dout(10) << fmt::format("{}: stamp:{:s} ", __func__, stamp) << dendl;
747+
dout(10) << fmt::format("{}: calculated stamp:{:s}", __func__, stamp)
748+
<< dendl;
770749
asok_response_section(f, true, scrub_level, stamp);
771750

772751
if (scrub_level == scrub_level_t::deep) {
@@ -2080,7 +2059,7 @@ void PgScrubber::on_digest_updates()
20802059
void PgScrubber::on_mid_scrub_abort(Scrub::delay_cause_t issue)
20812060
{
20822061
if (!m_scrub_job->is_registered()) {
2083-
dout(10) << fmt::format(
2062+
dout(5) << fmt::format(
20842063
"{}: PG not registered for scrubbing on this OSD. Won't "
20852064
"requeue!",
20862065
__func__)
@@ -2110,7 +2089,6 @@ void PgScrubber::on_mid_scrub_abort(Scrub::delay_cause_t issue)
21102089
std::max(current_targ.urgency(), aborted_target.urgency());
21112090
curr_sched.scheduled_at =
21122091
std::min(curr_sched.scheduled_at, abrt_sched.scheduled_at);
2113-
curr_sched.deadline = std::min(curr_sched.deadline, abrt_sched.deadline);
21142092
curr_sched.not_before =
21152093
std::min(curr_sched.not_before, abrt_sched.not_before);
21162094

src/osd/scrubber/scrub_job.cc

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,13 @@ void ScrubJob::adjust_shallow_schedule(
110110
if (ScrubJob::requires_randomization(shallow_target.urgency())) {
111111
utime_t adj_not_before = last_scrub;
112112
utime_t adj_target = last_scrub;
113-
sh_times.deadline = adj_target;
114113

115114
// add a random delay to the proposed scheduled time
116115
adj_target += app_conf.shallow_interval;
117116
double r = rand() / (double)RAND_MAX;
118117
adj_target +=
119-
app_conf.shallow_interval * app_conf.interval_randomize_ratio * r;
118+
app_conf.shallow_interval * app_conf.interval_randomize_ratio * r;
120119

121-
// the deadline can be updated directly into the scrub-job
122-
if (app_conf.max_shallow) {
123-
sh_times.deadline += *app_conf.max_shallow;
124-
} else {
125-
sh_times.deadline = utime_t{};
126-
}
127120
if (adj_not_before < adj_target) {
128121
adj_not_before = adj_target;
129122
}
@@ -132,20 +125,33 @@ void ScrubJob::adjust_shallow_schedule(
132125

133126
} else {
134127

135-
// the target time is already set. Make sure to reset the n.b. and
136-
// the (irrelevant) deadline
128+
// the target time is already set. Make sure to reset the n.b.
137129
sh_times.not_before = sh_times.scheduled_at;
138-
sh_times.deadline = sh_times.scheduled_at;
139130
}
140131

141132
dout(10) << fmt::format(
142-
"adjusted: nb:{:s} target:{:s} deadline:{:s} ({})",
143-
sh_times.not_before, sh_times.scheduled_at, sh_times.deadline,
144-
state_desc())
133+
"adjusted: nb:{:s} target:{:s} ({})", sh_times.not_before,
134+
sh_times.scheduled_at, state_desc())
145135
<< dendl;
146136
}
147137

148138

139+
double ScrubJob::guaranteed_offset(
140+
scrub_level_t s_or_d,
141+
const Scrub::sched_conf_t& app_conf)
142+
{
143+
if (s_or_d == scrub_level_t::deep) {
144+
// use the sdv of the deep scrub distribution, times 3 (3-sigma...)
145+
const double sdv = app_conf.deep_interval * app_conf.deep_randomize_ratio;
146+
// note: the '+10.0' is there just to guarantee inequality if '._ratio' is 0
147+
return app_conf.deep_interval + abs(3 * sdv) + 10.0;
148+
}
149+
150+
// shallow scrub
151+
return app_conf.shallow_interval * (2.0 + app_conf.interval_randomize_ratio);
152+
}
153+
154+
149155
void ScrubJob::operator_forced(scrub_level_t s_or_d, scrub_type_t scrub_type)
150156
{
151157
auto& trgt = get_target(s_or_d);
@@ -239,46 +245,32 @@ void ScrubJob::adjust_deep_schedule(
239245
auto& dp_times = deep_target.sched_info.schedule; // shorthand
240246

241247
if (ScrubJob::requires_randomization(deep_target.urgency())) {
242-
utime_t adj_not_before = last_deep;
243248
utime_t adj_target = last_deep;
244-
dp_times.deadline = adj_target;
245249

246250
// add a random delay to the proposed scheduled time
247251
const double sdv = app_conf.deep_interval * app_conf.deep_randomize_ratio;
248252
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);
253+
auto next_delay = std::clamp(
254+
normal_dist(random_gen), app_conf.deep_interval - 2 * sdv,
255+
app_conf.deep_interval + 2 * sdv);
252256
adj_target += next_delay;
253257
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-
// the deadline can be updated directly into the scrub-job
261-
if (app_conf.max_shallow) {
262-
dp_times.deadline += *app_conf.max_shallow; // RRR fix
263-
} else {
264-
dp_times.deadline = utime_t{};
265-
}
266-
if (adj_not_before < adj_target) {
267-
adj_not_before = adj_target;
268-
}
258+
"deep scrubbing: next_delay={:.0f} (interval={:.0f}, "
259+
"ratio={:.3f}), adjusted:{:s}",
260+
next_delay, app_conf.deep_interval,
261+
app_conf.deep_randomize_ratio, adj_target)
262+
<< dendl;
263+
269264
dp_times.scheduled_at = adj_target;
270-
dp_times.not_before = adj_not_before;
265+
dp_times.not_before = adj_target;
271266
} else {
272-
// the target time is already set. Make sure to reset the n.b. and
273-
// the (irrelevant) deadline
267+
// the target time is already set. The n.b. is set to same
274268
dp_times.not_before = dp_times.scheduled_at;
275-
dp_times.deadline = dp_times.scheduled_at;
276269
}
277270

278271
dout(10) << fmt::format(
279-
"adjusted: nb:{:s} target:{:s} deadline:{:s} ({})",
280-
dp_times.not_before, dp_times.scheduled_at, dp_times.deadline,
281-
state_desc())
272+
"adjusted: nb:{:s} target:{:s} ({})", dp_times.not_before,
273+
dp_times.scheduled_at, state_desc())
282274
<< dendl;
283275
}
284276

@@ -366,7 +358,6 @@ void ScrubJob::dump(ceph::Formatter* f) const
366358
f->dump_stream("pgid") << pgid;
367359
f->dump_stream("sched_time") << get_sched_time();
368360
f->dump_stream("orig_sched_time") << sch.scheduled_at;
369-
f->dump_stream("deadline") << sch.deadline;
370361
f->dump_bool("forced", entry.urgency >= urgency_t::operator_requested);
371362
}
372363

0 commit comments

Comments
 (0)