osd max backfills: 1
osd scrub min interval: 60
osd scrub max interval: 120
+ osd max backfills: 3
+ osd snap trim sleep: 2
- thrashosds:
timeout: 1200
chance_pgnum_grow: 1
osd scrub min interval: 60
osd scrub max interval: 120
filestore odsync write: true
+ osd max backfills: 2
+ osd snap trim sleep: .5
- thrashosds:
timeout: 1200
chance_pgnum_grow: 2
OPTION(osd_recovery_thread_timeout, OPT_INT, 30)
OPTION(osd_recovery_thread_suicide_timeout, OPT_INT, 300)
OPTION(osd_recovery_sleep, OPT_FLOAT, 0) // seconds to sleep between recovery ops
-OPTION(osd_snap_trim_sleep, OPT_FLOAT, 0)
+OPTION(osd_snap_trim_sleep, OPT_DOUBLE, 0)
OPTION(osd_scrub_invalid_stats, OPT_BOOL, true)
OPTION(osd_remove_thread_timeout, OPT_INT, 60*60)
OPTION(osd_remove_thread_suicide_timeout, OPT_INT, 10*60*60)
remote_reserver(&reserver_finisher, cct->_conf->osd_max_backfills,
cct->_conf->osd_min_recovery_priority),
pg_temp_lock("OSDService::pg_temp_lock"),
+ snap_sleep_lock("OSDService::snap_sleep_lock"),
+ snap_sleep_timer(
+ osd->client_messenger->cct, snap_sleep_lock, false /* relax locking */),
snap_reserver(&reserver_finisher,
cct->_conf->osd_max_trimming_pgs),
map_cache_lock("OSDService::map_lock"),
Mutex::Locker l(backfill_request_lock);
backfill_request_timer.shutdown();
}
+
+ {
+ Mutex::Locker l(snap_sleep_lock);
+ snap_sleep_timer.shutdown();
+ }
+
osdmap = OSDMapRef();
next_osdmap = OSDMapRef();
}
objecter->set_client_incarnation(0);
watch_timer.init();
agent_timer.init();
+ snap_sleep_timer.init();
agent_thread.create("osd_srv_agent");
}
ceph_clock_now(cct),
entity_inst_t())));
}
+
+ Mutex snap_sleep_lock;
+ SafeTimer snap_sleep_timer;
AsyncReserver<spg_t> snap_reserver;
void queue_for_scrub(PG *pg) {
void ReplicatedPG::snap_trimmer(epoch_t queued)
{
- if (g_conf->osd_snap_trim_sleep > 0) {
- unlock();
- utime_t t;
- t.set_from_double(g_conf->osd_snap_trim_sleep);
- t.sleep();
- lock();
- dout(20) << __func__ << " slept for " << t << dendl;
- }
if (deleting || pg_has_reset_since(queued)) {
return;
}
pending = nullptr;
if (!pg->is_primary() || !pg->is_active() || !pg->is_clean() ||
- pg->scrubber.active) {
+ pg->scrubber.active || pg->snap_trimq.empty()) {
post_event(SnapTrim());
return transit< NotTrimming >();
}
in_flight.insert(pos);
pg->simple_opc_submit(std::move(ctx));
}
- return discard_event();
+ return transit< WaitTrimTimer >();
}
/* WaitingOnReplicasObjects */
struct SnapTrimReserved : boost::statechart::event< SnapTrimReserved > {
SnapTrimReserved() : boost::statechart::event< SnapTrimReserved >() {}
};
+ struct SnapTrimTimerReady : boost::statechart::event< SnapTrimTimerReady > {
+ SnapTrimTimerReady() : boost::statechart::event< SnapTrimTimerReady >() {}
+ };
+
struct SnapTrimmer : public boost::statechart::state_machine< SnapTrimmer, NotTrimming > {
ReplicatedPG *pg;
set<hobject_t, hobject_t::BitwiseComparator> in_flight;
}
};
+ struct WaitTrimTimer : boost::statechart::state< WaitTrimTimer, Trimming >, NamedState {
+ typedef boost::mpl::list <
+ boost::statechart::custom_reaction< SnapTrimTimerReady >
+ > reactions;
+ Context *wakeup = nullptr;
+ bool slept = false;
+ explicit WaitTrimTimer(my_context ctx)
+ : my_base(ctx),
+ NamedState(context< SnapTrimmer >().pg->cct, "Trimming/WaitTrimTimer") {
+ context< SnapTrimmer >().log_enter(state_name);
+ struct OnTimer : Context {
+ ReplicatedPGRef pg;
+ epoch_t epoch;
+ OnTimer(ReplicatedPGRef pg, epoch_t epoch) : pg(pg), epoch(epoch) {}
+ void finish(int) override {
+ pg->lock();
+ if (!pg->pg_has_reset_since(epoch))
+ pg->snap_trimmer_machine.process_event(SnapTrimTimerReady());
+ pg->unlock();
+ }
+ };
+ auto *pg = context< SnapTrimmer >().pg;
+ if (pg->cct->_conf->osd_snap_trim_sleep > 0) {
+ wakeup = new OnTimer{pg, pg->get_osdmap()->get_epoch()};
+ Mutex::Locker l(pg->osd->snap_sleep_lock);
+ pg->osd->snap_sleep_timer.add_event_after(
+ pg->cct->_conf->osd_snap_trim_sleep, wakeup);
+ slept = true;
+ } else {
+ post_event(SnapTrimTimerReady());
+ }
+ }
+ void exit() {
+ context< SnapTrimmer >().log_exit(state_name, enter_time);
+ auto *pg = context< SnapTrimmer >().pg;
+ if (wakeup) {
+ Mutex::Locker l(pg->osd->snap_sleep_lock);
+ pg->osd->snap_sleep_timer.cancel_event(wakeup);
+ wakeup = nullptr;
+ }
+ }
+ boost::statechart::result react(const SnapTrimTimerReady &) {
+ wakeup = nullptr;
+ auto *pg = context< SnapTrimmer >().pg;
+ if (!pg->is_primary() || !pg->is_active() || !pg->is_clean() ||
+ pg->scrubber.active) {
+ post_event(SnapTrim());
+ return transit< NotTrimming >();
+ } else {
+ if (slept)
+ post_event(SnapTrim());
+ return transit< TrimmingObjects >();
+ }
+ }
+ };
+
struct WaitingOnReplicas : boost::statechart::state< WaitingOnReplicas, Trimming >, NamedState {
typedef boost::mpl::list <
boost::statechart::custom_reaction< SnapTrim >,