From 06a7bf439139023a8dd1d4c1e675432c84c6e10c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 7 Mar 2019 08:38:02 -0600 Subject: [PATCH] osd/PG: adjust pg history on fabricated merge target if necessary 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 --- src/osd/PG.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/osd/PG.cc b/src/osd/PG.cc index db6b22d90b7..3c1d8dc9bbb 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -2816,6 +2816,26 @@ void PG::merge_from(map& 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; -- 2.39.5