summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Just <sam.just@inktank.com>2013-09-17 08:26:51 -0700
committerSamuel Just <sam.just@inktank.com>2013-09-19 12:52:53 -0700
commit36d2226211f7b3f5fb79763e30e59e5a1e6676cf (patch)
treea352bddf6706e331635d8456afcf47375750655d
parentd422ce68f2ceb662b42c06f32246733b49c3191b (diff)
downloadceph-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.h1
-rw-r--r--src/osd/ReplicatedPG.cc50
-rw-r--r--src/osd/ReplicatedPG.h6
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);