diff options
author | Samuel Just <sam.just@inktank.com> | 2012-07-12 17:19:43 -0700 |
---|---|---|
committer | Samuel Just <sam.just@inktank.com> | 2012-07-13 10:19:24 -0700 |
commit | 5924f8e4a8c29e6de326a9e8576c30109cdc0e07 (patch) | |
tree | 5ed9c3f5e35e898d12e7e5d6926f35e0c58712e0 | |
parent | 3dd65a897bcf3b83783966fde9e701ba2606ad07 (diff) | |
download | ceph-5924f8e4a8c29e6de326a9e8576c30109cdc0e07.tar.gz |
PG: merge_log always use stats from authoritative replica
If the osd recieving the log has divergent entries, it will
also have a "divergent" stat structure. In general, it suffices
to simply trust the stat structure shipped with the authoritative
log and info since merge_log is only used to merge an authoritative
log.
Probably fixes #2769.
In cases like #2769, this bug can result in a primary with a stat
structure which double counts an operation: once for the
divergent operation, and once for the replay. It turned up
in a regression suite run as a scrub stat mismatch.
Signed-off-by: Samuel Just <sam.just@inktank.com>
-rw-r--r-- | src/osd/PG.cc | 9 | ||||
-rw-r--r-- | src/osd/PG.h | 9 |
2 files changed, 14 insertions, 4 deletions
diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 14c5d581a39..f026c2c719c 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -483,6 +483,11 @@ void PG::merge_log(ObjectStore::Transaction& t, changed = true; } + if (oinfo.stats.reported < info.stats.reported) // make sure reported always increases + oinfo.stats.reported = info.stats.reported; + if (info.last_backfill.is_max()) + info.stats = oinfo.stats; + // do we have divergent entries to throw out? if (olog.head < log.head) { rewind_divergent_log(t, olog.head); @@ -548,10 +553,6 @@ void PG::merge_log(ObjectStore::Transaction& t, log.index(); info.last_update = log.head = olog.head; - if (oinfo.stats.reported < info.stats.reported) // make sure reported always increases - oinfo.stats.reported = info.stats.reported; - if (info.last_backfill.is_max()) - info.stats = oinfo.stats; // process divergent items if (!divergent.empty()) { diff --git a/src/osd/PG.h b/src/osd/PG.h index f5a1070beed..d3eda0b927d 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -697,6 +697,15 @@ public: pg_missing_t& omissing, int from); bool proc_replica_info(int from, const pg_info_t &info); bool merge_old_entry(ObjectStore::Transaction& t, pg_log_entry_t& oe); + + /** + * Merges authoratative log/info into current log/info/store + * + * @param [in,out] t used to delete obsolete objects + * @param [in,out] oinfo recieved authoritative info + * @param [in,out] olog recieved authoritative log + * @param [in] from peer which sent the information + */ void merge_log(ObjectStore::Transaction& t, pg_info_t &oinfo, pg_log_t &olog, int from); void rewind_divergent_log(ObjectStore::Transaction& t, eversion_t newhead); bool search_for_missing(const pg_info_t &oinfo, const pg_missing_t *omissing, |