PG: improve find_best_info

07f853db39 is actually too conservative,
it suffices to find any info with a last_update of at least the least
last_update from the last period to go active.  An info from a previous
interval is acceptable if the last interval never reported a commited
operation and thus still has the same last_update.

Signed-off-by: Samuel Just <sam.just@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
This commit is contained in:
Samuel Just 2012-06-19 09:11:57 -07:00
parent 0d8970fc81
commit 4ec9633653
2 changed files with 25 additions and 9 deletions

View File

@ -928,7 +928,22 @@ void PG::clear_primary_state()
*/
map<int, pg_info_t>::const_iterator PG::find_best_info(const map<int, pg_info_t> &infos) const
{
epoch_t last_epoch_started = 0;
eversion_t min_last_update_acceptable = eversion_t::max();
epoch_t max_last_epoch_started_found = 0;
for (map<int, pg_info_t>::const_iterator i = infos.begin();
i != infos.end();
++i) {
if (max_last_epoch_started_found < i->second.history.last_epoch_started) {
min_last_update_acceptable = eversion_t::max();
max_last_epoch_started_found = i->second.history.last_epoch_started;
}
if (max_last_epoch_started_found == i->second.history.last_epoch_started) {
if (min_last_update_acceptable > i->second.last_update)
min_last_update_acceptable = i->second.last_update;
}
}
assert(min_last_update_acceptable != eversion_t::max());
map<int, pg_info_t>::const_iterator best = infos.end();
// find osd with newest last_update. if there are multiples, prefer
// - a longer tail, if it brings another peer into log contiguity
@ -936,15 +951,9 @@ map<int, pg_info_t>::const_iterator PG::find_best_info(const map<int, pg_info_t>
for (map<int, pg_info_t>::const_iterator p = infos.begin();
p != infos.end();
++p) {
// Only consider peers with the most recent last_epoch_started found
if (p->second.history.last_epoch_started > last_epoch_started) {
last_epoch_started = p->second.history.last_epoch_started;
if (best != infos.end() &&
last_epoch_started > best->second.history.last_epoch_started)
best = infos.end();
} else if (p->second.history.last_epoch_started < last_epoch_started) {
// Only consider peers with last_update >= min_last_update_acceptable
if (p->second.last_update < min_last_update_acceptable)
continue;
}
// Disquality anyone who is incomplete (not fully backfilled)
if (p->second.is_incomplete())
continue;

View File

@ -417,6 +417,13 @@ public:
eversion_t(bufferlist& bl) : __pad(0) { decode(bl); }
static eversion_t max() {
eversion_t max;
max.version -= 1;
max.epoch -= 1;
return max;
}
operator ceph_eversion() {
ceph_eversion c;
c.epoch = epoch;