From: Samuel Just Date: Wed, 24 Sep 2014 20:55:47 +0000 (-0700) Subject: ReplicatedPG: clean out completed trimmed objects as we go X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1f9961221f7cbec2814612f444dc669f94bed69d;p=ceph.git ReplicatedPG: clean out completed trimmed objects as we go Also, explicitely maintain a max number of concurrently trimming objects. Fixes: 9113 Backport: dumpling, firefly, giant Signed-off-by: Samuel Just Conflicts: src/common/config_opts.h src/osd/ReplicatedPG.cc --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 1fd91c327d83..d688f5b3d29b 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -427,6 +427,10 @@ OPTION(osd_heartbeat_addr, OPT_ADDR, entity_addr_t()) OPTION(osd_heartbeat_interval, OPT_INT, 6) // (seconds) how often we ping peers OPTION(osd_heartbeat_grace, OPT_INT, 20) // (seconds) how long before we decide a peer has failed OPTION(osd_heartbeat_min_peers, OPT_INT, 10) // minimum number of peers + +// max number of parallel snap trims/pg +OPTION(osd_pg_max_concurrent_snap_trims, OPT_U64, 2) + OPTION(osd_mon_heartbeat_interval, OPT_INT, 30) // (seconds) how often to ping monitor if no peers OPTION(osd_mon_report_interval_max, OPT_INT, 120) OPTION(osd_mon_report_interval_min, OPT_INT, 5) // pg stats, failures, up_thru, boot. diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 443e98d3d80d..5bd2e0c7fc6b 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -7898,33 +7898,48 @@ boost::statechart::result ReplicatedPG::TrimmingObjects::react(const SnapTrim&) dout(10) << "TrimmingObjects: trimming snap " << snap_to_trim << dendl; - // Get next - int r = pg->snap_mapper.get_next_object_to_trim(snap_to_trim, &pos); - if (r != 0 && r != -ENOENT) { - derr << __func__ << ": get_next returned " << cpp_strerror(r) << dendl; - assert(0); - } else if (r == -ENOENT) { - // Done! - dout(10) << "TrimmingObjects: got ENOENT" << dendl; - post_event(SnapTrim()); - return transit< WaitingOnReplicas >(); + for (set::iterator i = repops.begin(); + i != repops.end(); + ) { + if ((*i)->done) { + (*i)->put(); + repops.erase(i++); + } else { + ++i; + } } - dout(10) << "TrimmingObjects react trimming " << pos << dendl; - RepGather *repop = pg->trim_object(pos); - assert(repop); + while (repops.size() < g_conf->osd_pg_max_concurrent_snap_trims) { + // Get next + hobject_t old_pos = pos; + int r = pg->snap_mapper.get_next_object_to_trim(snap_to_trim, &pos); + if (r != 0 && r != -ENOENT) { + derr << __func__ << ": get_next returned " << cpp_strerror(r) << dendl; + assert(0); + } else if (r == -ENOENT) { + // Done! + dout(10) << "TrimmingObjects: got ENOENT" << dendl; + post_event(SnapTrim()); + return transit< WaitingOnReplicas >(); + } - repop->queue_snap_trimmer = true; - eversion_t old_last_update = pg->pg_log.get_head(); - bool old_exists = repop->obc->obs.exists; - uint64_t old_size = repop->obc->obs.oi.size; - eversion_t old_version = repop->obc->obs.oi.version; + dout(10) << "TrimmingObjects react trimming " << pos << dendl; + RepGather *repop = pg->trim_object(pos); + assert(repop); + + repop->queue_snap_trimmer = true; - pg->append_log(repop->ctx->log, eversion_t(), repop->ctx->local_t); - pg->issue_repop(repop, repop->ctx->mtime, old_last_update, old_exists, old_size, old_version); - pg->eval_repop(repop); + eversion_t old_last_update = pg->pg_log.get_head(); + bool old_exists = repop->obc->obs.exists; + uint64_t old_size = repop->obc->obs.oi.size; + eversion_t old_version = repop->obc->obs.oi.version; - repops.insert(repop); + pg->append_log(repop->ctx->log, eversion_t(), repop->ctx->local_t); + pg->issue_repop(repop, repop->ctx->mtime, old_last_update, old_exists, old_size, old_version); + pg->eval_repop(repop); + + repops.insert(repop); + } return discard_event(); } /* WaitingOnReplicasObjects */ @@ -7957,7 +7972,7 @@ boost::statechart::result ReplicatedPG::WaitingOnReplicas::react(const SnapTrim& for (set::iterator i = repops.begin(); i != repops.end(); repops.erase(i++)) { - if (!(*i)->applied || !(*i)->waitfor_ack.empty()) { + if (!(*i)->done) { return discard_event(); } else { (*i)->put();