diff options
author | Samuel Just <sam.just@inktank.com> | 2013-09-17 08:26:51 -0700 |
---|---|---|
committer | Samuel Just <sam.just@inktank.com> | 2013-09-19 12:52:53 -0700 |
commit | 36d2226211f7b3f5fb79763e30e59e5a1e6676cf (patch) | |
tree | a352bddf6706e331635d8456afcf47375750655d | |
parent | d422ce68f2ceb662b42c06f32246733b49c3191b (diff) | |
download | ceph-36d2226211f7b3f5fb79763e30e59e5a1e6676cf.tar.gz |
ReplicatedPG: don't rescan the local collection if we can avoid it
Signed-off-by: Samuel Just <sam.just@inktank.com>
-rw-r--r-- | src/osd/PG.h | 1 | ||||
-rw-r--r-- | src/osd/ReplicatedPG.cc | 50 | ||||
-rw-r--r-- | src/osd/ReplicatedPG.h | 6 |
3 files changed, 49 insertions, 8 deletions
diff --git a/src/osd/PG.h b/src/osd/PG.h index 74809eea268..a11b2076c33 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -439,6 +439,7 @@ protected: */ struct BackfillInterval { // info about a backfill interval on a peer + eversion_t version; /// version at which the scan occurred map<hobject_t,eversion_t> objects; hobject_t begin; hobject_t end; diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 40838940840..15191dae597 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -7933,14 +7933,8 @@ int ReplicatedPG::recover_backfill( int local_min = osd->store->get_ideal_list_min(); int local_max = osd->store->get_ideal_list_max(); - // re-scan our local interval to cope with recent changes - // FIXME: we could track the eversion_t when we last scanned, and invalidate - // that way. or explicitly modify/invalidate when we actually change specific - // objects. - dout(10) << " rescanning local backfill_info from " << backfill_pos << dendl; - backfill_info.clear(); - osr->flush(); - scan_range(backfill_pos, local_min, local_max, &backfill_info, handle); + // update our local interval to cope with recent changes + update_range(&backfill_info, handle); int ops = 0; map<hobject_t, pair<eversion_t, eversion_t> > to_push; @@ -8122,12 +8116,52 @@ void ReplicatedPG::prep_backfill_object_push( h); } +void ReplicatedPG::update_range( + BackfillInterval *bi, + ThreadPool::TPHandle &handle) +{ + int local_min = osd->store->get_ideal_list_min(); + int local_max = osd->store->get_ideal_list_max(); + if (bi->version >= info.last_update) { + dout(10) << __func__<< ": bi is current " << dendl; + assert(bi->version == info.last_update); + return; + } else if (bi->version >= info.log_tail) { + dout(10) << __func__<< ": bi is old, can be updated with log" << dendl; + list<pg_log_entry_t>::const_iterator i = + pg_log.get_log().log.end(); + while (i != pg_log.get_log().log.begin() && + i->version > bi->version) { + --i; + } + + for (; i != pg_log.get_log().log.end(); ++i) { + if (i->is_update()) { + bi->objects.erase(i->soid); + bi->objects.insert( + make_pair( + i->soid, + i->version)); + } else if (i->is_delete()) { + bi->objects.erase(i->soid); + } + } + } else { + dout(10) << __func__<< ": bi is old, rescanning local backfill_info" + << dendl; + backfill_info.clear(); + osr->flush(); + scan_range(backfill_pos, local_min, local_max, &backfill_info, handle); + } +} + void ReplicatedPG::scan_range( hobject_t begin, int min, int max, BackfillInterval *bi, ThreadPool::TPHandle &handle) { assert(is_locked()); dout(10) << "scan_range from " << begin << dendl; + bi->version = info.last_update; bi->begin = begin; bi->objects.clear(); // for good measure diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index a4e5ac1e1a1..5105207694b 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -624,6 +624,12 @@ protected: ThreadPool::TPHandle &handle ); + /// Update a hash range to reflect changes since the last scan + void update_range( + BackfillInterval *bi, ///< [in,out] interval to update + ThreadPool::TPHandle &handle ///< [in] tp handle + ); + void prep_backfill_object_push( hobject_t oid, eversion_t v, eversion_t have, int peer, PGBackend::RecoveryHandle *h); |