]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd/PG: adjust pg history on fabricated merge target if necessary
authorSage Weil <sage@redhat.com>
Thu, 7 Mar 2019 14:38:02 +0000 (08:38 -0600)
committerSage Weil <sage@redhat.com>
Thu, 7 Mar 2019 14:38:06 +0000 (08:38 -0600)
If we have to fabricate the merge target, we use the pg_history from
the soruce to start with, since it is normally close enough.  However, if
we get a last_epoch_clean that is > the same_interval_since, then on the
next interval change the past_intervals will have a start that is after
last_epoch_clean, resulting in a past_intervals assert.

Avoid this situation by adjusting the pg_history backwards to match
last_epoch_started (which is always <= last_epoch_clean).  This makes
the most sense because these values came from the *real* target, while
the history was from the source.

Fixes: http://tracker.ceph.com/issues/38623
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/PG.cc

index db6b22d90b7f2ec6d50530038ae8059e75f8d75a..3c1d8dc9bbb28e99ec98eb742066777ac1b020eb 100644 (file)
@@ -2816,6 +2816,26 @@ void PG::merge_from(map<spg_t,PGRef>& sources, RecoveryCtx *rctx,
               << pib.first << ", adjusting start backwards" << dendl;
       past_intervals.adjust_start_backwards(info.history.last_epoch_clean);
     }
+
+    // Similarly, if the same_interval_since value is later than
+    // last_epoch_clean, the next interval change will result in a
+    // past_interval start that is later than last_epoch_clean.  This
+    // can happen if we use the pg_history values from the merge
+    // source.  Adjust the same_interval_since value backwards if that
+    // happens.  (We trust the les and lec values more because they came from
+    // the real target, whereas the history value we stole from the source.)
+    if (info.history.last_epoch_started < info.history.same_interval_since) {
+      dout(10) << __func__ << " last_epoch_started "
+              << info.history.last_epoch_started << " < same_interval_since "
+              << info.history.same_interval_since
+              << ", adjusting pg_history backwards" << dendl;
+      info.history.same_interval_since = info.history.last_epoch_clean;
+      // make sure same_{up,primary}_since are <= same_interval_since
+      info.history.same_up_since = std::min(
+       info.history.same_up_since, info.history.same_interval_since);
+      info.history.same_primary_since = std::min(
+       info.history.same_primary_since, info.history.same_interval_since);
+    }
   }
 
   dirty_info = true;