From 590c4979d40ea2073da8180140303ac067d87cc4 Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Fri, 13 Oct 2017 14:08:28 +0800 Subject: [PATCH] osd/PrimaryLogPG: arrange recovery order by number of missing objects Replica which has the shortest missing list (smallest amount of objects to recover) should go recovering first, since it can be technically brought back to normal sooner than others. Signed-off-by: xie xingguo --- src/osd/PrimaryLogPG.cc | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 28df7e64fe5..4bb5ee452e0 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -11491,11 +11491,31 @@ uint64_t PrimaryLogPG::recover_replicas(uint64_t max, ThreadPool::TPHandle &hand // this is FAR from an optimal recovery order. pretty lame, really. assert(!actingbackfill.empty()); - for (set::iterator i = actingbackfill.begin(); - i != actingbackfill.end(); - ++i) { - if (*i == get_primary()) continue; - pg_shard_t peer = *i; + // choose replicas to recover, replica has the shortest missing list first + // so we can bring it back to normal ASAP + std::vector> replicas_by_num_missing; + replicas_by_num_missing.reserve(actingbackfill.size() - 1); + for (auto &p: actingbackfill) { + if (p == get_primary()) { + continue; + } + auto pm = peer_missing.find(p); + assert(pm != peer_missing.end()); + auto nm = pm->second.num_missing(); + if (nm != 0) { + replicas_by_num_missing.push_back(make_pair(nm, p)); + } + } + // sort by number of missing objects, in ascending order. + std::sort(replicas_by_num_missing.begin(), replicas_by_num_missing.end(), + [](const std::pair &lhs, + const std::pair &rhs) { + return lhs.first < rhs.first; + } + ); + for (auto &replica: replicas_by_num_missing) { + pg_shard_t &peer = replica.second; + assert(peer != get_primary()); map::const_iterator pm = peer_missing.find(peer); assert(pm != peer_missing.end()); map::const_iterator pi = peer_info.find(peer); @@ -11553,8 +11573,7 @@ uint64_t PrimaryLogPG::recover_replicas(uint64_t max, ThreadPool::TPHandle &hand dout(10) << __func__ << ": recover_object_replicas(" << soid << ")" << dendl; map::const_iterator r = m.get_items().find(soid); - started += prep_object_replica_pushes(soid, r->second.need, - h); + started += prep_object_replica_pushes(soid, r->second.need, h); } } -- 2.39.5