]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PG: _update_calc_stats: backfill targets do not always affect degraded
authorSage Weil <sage@redhat.com>
Sun, 22 Oct 2017 03:16:27 +0000 (22:16 -0500)
committerDavid Zafman <dzafman@redhat.com>
Mon, 23 Oct 2017 17:05:08 +0000 (10:05 -0700)
Our progress on a backfill target should only count toward degraded if
the target is needed in order for us to reach the target pool size.  If
we have remapped other complete copies, we can backfill and not be degraded
at all.  And we may be some combination of the two if there are multiple
backfill targets; use the target(s) with the most objects.

Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/PG.cc

index 6bae2a746c20fb902784ed6b1a0dbada5b00bba9..32efb9118dea4c251ccfd211fc8b511d50ad2e9f 100644 (file)
@@ -2633,6 +2633,9 @@ void PG::_update_calc_stats()
       }
     }
 
+    // Objects backfilled, sorted by # objects.
+    set<pair<int64_t,pg_shard_t>> backfill_target_objects;
+
     assert(!actingbackfill.empty());
     for (set<pg_shard_t>::iterator i = actingbackfill.begin();
         i != actingbackfill.end();
@@ -2662,10 +2665,24 @@ void PG::_update_calc_stats()
          misplaced += osd_objects;
       } else {
         // If this peer has more objects then it should, ignore them
-        int64_t osd_backfilled = MIN(num_objects, peer_info[p].stats.stats.sum.num_objects);
-        // Include computed backfilled objects on up nodes
-        object_copies += osd_backfilled;
-        backfilled += osd_backfilled;
+        int64_t osd_backfilled = MIN(num_objects,
+                                    peer_info[p].stats.stats.sum.num_objects);
+       backfill_target_objects.insert(make_pair(osd_backfilled, p));
+       backfilled += osd_backfilled;
+      }
+    }
+
+    // Only include backfill targets below pool size into the object_copies
+    // count.  Use the most-full targets.
+    int num_backfill_shards_seen = 0;
+    for (auto i = backfill_target_objects.rbegin();
+        i != backfill_target_objects.rend();
+        ++i) {
+      if (actingset.size() + num_backfill_shards_seen < pool.info.size) {
+       object_copies += i->first;
+       ++num_backfill_shards_seen;
+      } else {
+       break;
       }
     }