mirror of https://github.com/ceph/ceph
Merge pull request #60668 from ronen-fr/wip-rf-mconf
osd/scrub: cache frequently used configuration parameters Reviewed-by: Radoslaw Zarzynski <rzarzyns@redhat.com> Reviewed-by: Samuel Just <sjust@redhat.com>
This commit is contained in:
commit
801186f683
|
@ -50,7 +50,7 @@ public:
|
||||||
conf.remove_observer(this);
|
conf.remove_observer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator ValueT() const {
|
ValueT operator*() const {
|
||||||
return value_cache.load();
|
return value_cache.load();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -346,7 +346,7 @@ options:
|
||||||
default: 5
|
default: 5
|
||||||
see_also:
|
see_also:
|
||||||
- osd_scrub_chunk_max
|
- osd_scrub_chunk_max
|
||||||
with_legacy: true
|
with_legacy: false
|
||||||
- name: osd_scrub_chunk_max
|
- name: osd_scrub_chunk_max
|
||||||
type: int
|
type: int
|
||||||
level: advanced
|
level: advanced
|
||||||
|
@ -357,7 +357,7 @@ options:
|
||||||
default: 15
|
default: 15
|
||||||
see_also:
|
see_also:
|
||||||
- osd_scrub_chunk_min
|
- osd_scrub_chunk_min
|
||||||
with_legacy: true
|
with_legacy: false
|
||||||
- name: osd_shallow_scrub_chunk_min
|
- name: osd_shallow_scrub_chunk_min
|
||||||
type: int
|
type: int
|
||||||
level: advanced
|
level: advanced
|
||||||
|
@ -369,7 +369,7 @@ options:
|
||||||
see_also:
|
see_also:
|
||||||
- osd_shallow_scrub_chunk_max
|
- osd_shallow_scrub_chunk_max
|
||||||
- osd_scrub_chunk_min
|
- osd_scrub_chunk_min
|
||||||
with_legacy: true
|
with_legacy: false
|
||||||
- name: osd_shallow_scrub_chunk_max
|
- name: osd_shallow_scrub_chunk_max
|
||||||
type: int
|
type: int
|
||||||
level: advanced
|
level: advanced
|
||||||
|
@ -380,7 +380,7 @@ options:
|
||||||
see_also:
|
see_also:
|
||||||
- osd_shallow_scrub_chunk_min
|
- osd_shallow_scrub_chunk_min
|
||||||
- osd_scrub_chunk_max
|
- osd_scrub_chunk_max
|
||||||
with_legacy: true
|
with_legacy: false
|
||||||
# sleep between [deep]scrub ops
|
# sleep between [deep]scrub ops
|
||||||
- name: osd_scrub_sleep
|
- name: osd_scrub_sleep
|
||||||
type: float
|
type: float
|
||||||
|
|
|
@ -6006,7 +6006,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||||
object_info_t& oi = obs.oi;
|
object_info_t& oi = obs.oi;
|
||||||
const hobject_t& soid = oi.soid;
|
const hobject_t& soid = oi.soid;
|
||||||
const bool skip_data_digest = osd->store->has_builtin_csum() &&
|
const bool skip_data_digest = osd->store->has_builtin_csum() &&
|
||||||
osd->osd_skip_data_digest;
|
*osd->osd_skip_data_digest;
|
||||||
|
|
||||||
PGTransaction* t = ctx->op_t.get();
|
PGTransaction* t = ctx->op_t.get();
|
||||||
|
|
||||||
|
@ -6069,9 +6069,9 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||||
// munge ZERO -> TRUNCATE? (don't munge to DELETE or we risk hosing attributes)
|
// munge ZERO -> TRUNCATE? (don't munge to DELETE or we risk hosing attributes)
|
||||||
if (op.op == CEPH_OSD_OP_ZERO &&
|
if (op.op == CEPH_OSD_OP_ZERO &&
|
||||||
obs.exists &&
|
obs.exists &&
|
||||||
op.extent.offset < static_cast<Option::size_t>(osd->osd_max_object_size) &&
|
op.extent.offset < *osd->osd_max_object_size &&
|
||||||
op.extent.length >= 1 &&
|
op.extent.length >= 1 &&
|
||||||
op.extent.length <= static_cast<Option::size_t>(osd->osd_max_object_size) &&
|
op.extent.length <= *osd->osd_max_object_size &&
|
||||||
op.extent.offset + op.extent.length >= oi.size) {
|
op.extent.offset + op.extent.length >= oi.size) {
|
||||||
if (op.extent.offset >= oi.size) {
|
if (op.extent.offset >= oi.size) {
|
||||||
// no-op
|
// no-op
|
||||||
|
@ -6781,7 +6781,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||||
}
|
}
|
||||||
result = check_offset_and_length(
|
result = check_offset_and_length(
|
||||||
op.extent.offset, op.extent.length,
|
op.extent.offset, op.extent.length,
|
||||||
static_cast<Option::size_t>(osd->osd_max_object_size), get_dpp());
|
*osd->osd_max_object_size, get_dpp());
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6838,7 +6838,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||||
}
|
}
|
||||||
result = check_offset_and_length(
|
result = check_offset_and_length(
|
||||||
0, op.extent.length,
|
0, op.extent.length,
|
||||||
static_cast<Option::size_t>(osd->osd_max_object_size), get_dpp());
|
*osd->osd_max_object_size, get_dpp());
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6888,7 +6888,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||||
{ // zero
|
{ // zero
|
||||||
result = check_offset_and_length(
|
result = check_offset_and_length(
|
||||||
op.extent.offset, op.extent.length,
|
op.extent.offset, op.extent.length,
|
||||||
static_cast<Option::size_t>(osd->osd_max_object_size), get_dpp());
|
*osd->osd_max_object_size, get_dpp());
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6953,7 +6953,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||||
|
|
||||||
result = check_offset_and_length(
|
result = check_offset_and_length(
|
||||||
op.extent.offset, op.extent.length,
|
op.extent.offset, op.extent.length,
|
||||||
static_cast<Option::size_t>(osd->osd_max_object_size), get_dpp());
|
*osd->osd_max_object_size, get_dpp());
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
|
|
||||||
#include "./pg_scrubber.h" // '.' notation used to affect clang-format order
|
#include "./pg_scrubber.h" // '.' notation used to affect clang-format order
|
||||||
|
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <fmt/ranges.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include "common/ceph_time.h"
|
#include "common/ceph_time.h"
|
||||||
|
@ -824,21 +824,21 @@ namespace {
|
||||||
* an aux function to be used in select_range() below, to
|
* an aux function to be used in select_range() below, to
|
||||||
* select the correct chunk size based on the type of scrub
|
* select the correct chunk size based on the type of scrub
|
||||||
*/
|
*/
|
||||||
int size_from_conf(
|
int64_t size_from_conf(
|
||||||
bool is_deep,
|
bool is_deep,
|
||||||
const ceph::common::ConfigProxy& conf,
|
const ceph::common::ConfigProxy& conf,
|
||||||
std::string_view deep_opt,
|
const md_config_cacher_t<int64_t>& deep_opt,
|
||||||
std::string_view shallow_opt)
|
const md_config_cacher_t<int64_t>& shallow_opt)
|
||||||
{
|
{
|
||||||
if (!is_deep) {
|
if (!is_deep) {
|
||||||
auto sz = conf.get_val<int64_t>(shallow_opt);
|
auto sz = *shallow_opt;
|
||||||
if (sz != 0) {
|
if (sz != 0) {
|
||||||
// assuming '0' means that no distinction was yet configured between
|
// assuming '0' means that no distinction was yet configured between
|
||||||
// deep and shallow scrubbing
|
// deep and shallow scrubbing
|
||||||
return static_cast<int>(sz);
|
return sz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return static_cast<int>(conf.get_val<int64_t>(deep_opt));
|
return *deep_opt;
|
||||||
}
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
@ -917,16 +917,16 @@ std::optional<uint64_t> PgScrubber::select_range()
|
||||||
dout(20) << fmt::format(
|
dout(20) << fmt::format(
|
||||||
"{} {} mins: {}d {}s, max: {}d {}s", __func__,
|
"{} {} mins: {}d {}s, max: {}d {}s", __func__,
|
||||||
(m_is_deep ? "D" : "S"),
|
(m_is_deep ? "D" : "S"),
|
||||||
conf.get_val<int64_t>("osd_scrub_chunk_min"),
|
*osd_scrub_chunk_min,
|
||||||
conf.get_val<int64_t>("osd_shallow_scrub_chunk_min"),
|
*osd_shallow_scrub_chunk_min,
|
||||||
conf.get_val<int64_t>("osd_scrub_chunk_max"),
|
*osd_scrub_chunk_max,
|
||||||
conf.get_val<int64_t>("osd_shallow_scrub_chunk_max"))
|
*osd_shallow_scrub_chunk_max)
|
||||||
<< dendl;
|
<< dendl;
|
||||||
|
|
||||||
const int min_from_conf = size_from_conf(
|
const int min_from_conf = static_cast<int>(size_from_conf(
|
||||||
m_is_deep, conf, "osd_scrub_chunk_min", "osd_shallow_scrub_chunk_min");
|
m_is_deep, conf, osd_scrub_chunk_min, osd_shallow_scrub_chunk_min));
|
||||||
const int max_from_conf = size_from_conf(
|
const int max_from_conf = static_cast<int>(size_from_conf(
|
||||||
m_is_deep, conf, "osd_scrub_chunk_max", "osd_shallow_scrub_chunk_max");
|
m_is_deep, conf, osd_scrub_chunk_max, osd_shallow_scrub_chunk_max));
|
||||||
|
|
||||||
const int divisor = static_cast<int>(preemption_data.chunk_divisor());
|
const int divisor = static_cast<int>(preemption_data.chunk_divisor());
|
||||||
const int min_chunk_sz = std::max(3, min_from_conf / divisor);
|
const int min_chunk_sz = std::max(3, min_from_conf / divisor);
|
||||||
|
@ -1640,7 +1640,7 @@ void PgScrubber::replica_scrub_op(OpRequestRef op)
|
||||||
advance_token();
|
advance_token();
|
||||||
const auto& conf = m_pg->get_cct()->_conf;
|
const auto& conf = m_pg->get_cct()->_conf;
|
||||||
const int max_from_conf = size_from_conf(
|
const int max_from_conf = size_from_conf(
|
||||||
m_is_deep, conf, "osd_scrub_chunk_max", "osd_shallow_scrub_chunk_max");
|
m_is_deep, conf, osd_scrub_chunk_max, osd_shallow_scrub_chunk_max);
|
||||||
auto cost = get_scrub_cost(max_from_conf);
|
auto cost = get_scrub_cost(max_from_conf);
|
||||||
m_osds->queue_for_rep_scrub(m_pg,
|
m_osds->queue_for_rep_scrub(m_pg,
|
||||||
m_replica_request_priority,
|
m_replica_request_priority,
|
||||||
|
@ -2546,6 +2546,16 @@ PgScrubber::PgScrubber(PG* pg)
|
||||||
, m_pg_id{pg->pg_id}
|
, m_pg_id{pg->pg_id}
|
||||||
, m_osds{m_pg->osd}
|
, m_osds{m_pg->osd}
|
||||||
, m_pg_whoami{pg->pg_whoami}
|
, m_pg_whoami{pg->pg_whoami}
|
||||||
|
, osd_scrub_chunk_max{m_osds->cct->_conf, "osd_scrub_chunk_max"}
|
||||||
|
, osd_shallow_scrub_chunk_max{m_osds->cct->_conf,
|
||||||
|
"osd_shallow_scrub_chunk_max"}
|
||||||
|
, osd_scrub_chunk_min{m_osds->cct->_conf, "osd_scrub_chunk_min"}
|
||||||
|
, osd_shallow_scrub_chunk_min{m_osds->cct->_conf,
|
||||||
|
"osd_shallow_scrub_chunk_min"}
|
||||||
|
, osd_stats_update_period_scrubbing{
|
||||||
|
m_osds->cct->_conf, "osd_stats_update_period_scrubbing"}
|
||||||
|
, osd_stats_update_period_not_scrubbing{
|
||||||
|
m_osds->cct->_conf, "osd_stats_update_period_not_scrubbing"}
|
||||||
, preemption_data{pg}
|
, preemption_data{pg}
|
||||||
{
|
{
|
||||||
m_fsm = std::make_unique<ScrubMachine>(m_pg, this);
|
m_fsm = std::make_unique<ScrubMachine>(m_pg, this);
|
||||||
|
@ -2674,7 +2684,8 @@ const OSDMapRef& PgScrubber::get_osdmap() const
|
||||||
|
|
||||||
LoggerSinkSet& PgScrubber::get_logger() const { return *m_osds->clog.get(); }
|
LoggerSinkSet& PgScrubber::get_logger() const { return *m_osds->clog.get(); }
|
||||||
|
|
||||||
ostream &operator<<(ostream &out, const PgScrubber &scrubber) {
|
ostream& operator<<(ostream& out, const PgScrubber& scrubber)
|
||||||
|
{
|
||||||
return out << scrubber.m_flags;
|
return out << scrubber.m_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2788,16 +2799,14 @@ void PgScrubber::update_scrub_stats(ceph::coarse_real_clock::time_point now_is)
|
||||||
using clock = ceph::coarse_real_clock;
|
using clock = ceph::coarse_real_clock;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
||||||
const seconds period_active = seconds(m_pg->get_cct()->_conf.get_val<int64_t>(
|
const seconds period_active = seconds(*osd_stats_update_period_scrubbing);
|
||||||
"osd_stats_update_period_scrubbing"));
|
|
||||||
if (!period_active.count()) {
|
if (!period_active.count()) {
|
||||||
// a way for the operator to disable these stats updates
|
// a way for the operator to disable these stats updates
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const seconds period_inactive =
|
const seconds period_inactive = seconds(
|
||||||
seconds(m_pg->get_cct()->_conf.get_val<int64_t>(
|
*osd_stats_update_period_not_scrubbing +
|
||||||
"osd_stats_update_period_not_scrubbing") +
|
m_pg_id.pgid.m_seed % 30);
|
||||||
m_pg_id.pgid.m_seed % 30);
|
|
||||||
|
|
||||||
// determine the required update period, based on our current state
|
// determine the required update period, based on our current state
|
||||||
auto period{period_inactive};
|
auto period{period_inactive};
|
||||||
|
@ -2831,10 +2840,10 @@ void PgScrubber::update_scrub_stats(ceph::coarse_real_clock::time_point now_is)
|
||||||
|
|
||||||
// ///////////////////// preemption_data_t //////////////////////////////////
|
// ///////////////////// preemption_data_t //////////////////////////////////
|
||||||
|
|
||||||
PgScrubber::preemption_data_t::preemption_data_t(PG* pg) : m_pg{pg}
|
PgScrubber::preemption_data_t::preemption_data_t(PG* pg) : m_pg{pg},
|
||||||
|
osd_scrub_max_preemptions{pg->cct->_conf, "osd_scrub_max_preemptions"}
|
||||||
{
|
{
|
||||||
m_left = static_cast<int>(
|
m_left = *osd_scrub_max_preemptions;
|
||||||
m_pg->get_cct()->_conf.get_val<uint64_t>("osd_scrub_max_preemptions"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgScrubber::preemption_data_t::reset()
|
void PgScrubber::preemption_data_t::reset()
|
||||||
|
@ -2843,8 +2852,7 @@ void PgScrubber::preemption_data_t::reset()
|
||||||
|
|
||||||
m_preemptable = false;
|
m_preemptable = false;
|
||||||
m_preempted = false;
|
m_preempted = false;
|
||||||
m_left = static_cast<int>(
|
m_left = *osd_scrub_max_preemptions;
|
||||||
m_pg->cct->_conf.get_val<uint64_t>("osd_scrub_max_preemptions"));
|
|
||||||
m_size_divisor = 1;
|
m_size_divisor = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,8 @@ Main Scrubber interfaces:
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "common/config_proxy.h"
|
||||||
|
#include "common/config_cacher.h"
|
||||||
#include "osd/PG.h"
|
#include "osd/PG.h"
|
||||||
#include "osd/scrubber_common.h"
|
#include "osd/scrubber_common.h"
|
||||||
|
|
||||||
|
@ -895,6 +897,24 @@ class PgScrubber : public ScrubPgIF,
|
||||||
// scrub state.
|
// scrub state.
|
||||||
ceph::coarse_real_clock::time_point m_last_stat_upd{};
|
ceph::coarse_real_clock::time_point m_last_stat_upd{};
|
||||||
|
|
||||||
|
// ------------------ cached (frequently used) configuration values
|
||||||
|
|
||||||
|
/// initial (& max) number of objects to scrub in one pass - deep scrub
|
||||||
|
md_config_cacher_t<int64_t> osd_scrub_chunk_max;
|
||||||
|
/// initial (& max) number of objects to scrub in one pass - shallow
|
||||||
|
md_config_cacher_t<int64_t> osd_shallow_scrub_chunk_max;
|
||||||
|
|
||||||
|
/// chunk size won't be reduced (when preempted) below this
|
||||||
|
/// value (deep scrub)
|
||||||
|
md_config_cacher_t<int64_t> osd_scrub_chunk_min;
|
||||||
|
/// chunk size won't be reduced below this value (shallow scrub)
|
||||||
|
md_config_cacher_t<int64_t> osd_shallow_scrub_chunk_min;
|
||||||
|
|
||||||
|
/// stats update (publish_stats_to_osd()) interval while scrubbing
|
||||||
|
md_config_cacher_t<int64_t> osd_stats_update_period_scrubbing;
|
||||||
|
/// stats update interval while not scrubbing
|
||||||
|
md_config_cacher_t<int64_t> osd_stats_update_period_not_scrubbing;
|
||||||
|
|
||||||
// ------------ members used if we are a replica
|
// ------------ members used if we are a replica
|
||||||
|
|
||||||
epoch_t m_replica_min_epoch; ///< the min epoch needed to handle this message
|
epoch_t m_replica_min_epoch; ///< the min epoch needed to handle this message
|
||||||
|
@ -991,6 +1011,9 @@ class PgScrubber : public ScrubPgIF,
|
||||||
mutable ceph::mutex m_preemption_lock = ceph::make_mutex("preemption_lock");
|
mutable ceph::mutex m_preemption_lock = ceph::make_mutex("preemption_lock");
|
||||||
bool m_preemptable{false};
|
bool m_preemptable{false};
|
||||||
bool m_preempted{false};
|
bool m_preempted{false};
|
||||||
|
|
||||||
|
/// the number of preemptions allowed before we start blocking
|
||||||
|
md_config_cacher_t<uint64_t> osd_scrub_max_preemptions;
|
||||||
int m_left;
|
int m_left;
|
||||||
size_t m_size_divisor{1};
|
size_t m_size_divisor{1};
|
||||||
bool are_preemptions_left() const { return m_left > 0; }
|
bool are_preemptions_left() const { return m_left > 0; }
|
||||||
|
|
Loading…
Reference in New Issue