]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
PGLog, PrimaryLogPG: rebuild the missing set when the OSDMap flag is set
authorJosh Durgin <jdurgin@redhat.com>
Thu, 13 Jul 2017 18:44:21 +0000 (14:44 -0400)
committerJosh Durgin <jdurgin@redhat.com>
Wed, 19 Jul 2017 06:47:46 +0000 (02:47 -0400)
The recovery_deletes flag will only be set once, by the 'ceph osd
require-osd-release luminous' command.

This matches how we rebuild the missing set when reading it off disk in
read_log_and_missing().

Signed-off-by: Josh Durgin <jdurgin@redhat.com>
src/osd/PGLog.cc
src/osd/PGLog.h
src/osd/PrimaryLogPG.cc

index 99bbedf6ef61c6bedf06156caa2b19f52bb3531c..a54faafbe2edb816b57127369350fdf3bc2c6df3 100644 (file)
@@ -696,3 +696,60 @@ void PGLog::_write_log_and_missing(
   if (!to_remove.empty())
     t.omap_rmkeys(coll, log_oid, to_remove);
 }
+
+void PGLog::rebuild_missing_set_with_deletes(ObjectStore *store,
+                                            coll_t pg_coll,
+                                            const pg_info_t &info)
+{
+  // save entries not generated from the current log (e.g. added due
+  // to repair, EIO handling, or divergent_priors).
+  map<hobject_t, pg_missing_item> extra_missing;
+  for (const auto& p : missing.get_items()) {
+    if (!log.logged_object(p.first)) {
+      dout(20) << __func__ << " extra missing entry: " << p.first
+              << " " << p.second << dendl;
+      extra_missing[p.first] = p.second;
+    }
+  }
+  missing.clear();
+  missing.may_include_deletes = true;
+
+  // go through the log and add items that are not present or older
+  // versions on disk, just as if we were reading the log + metadata
+  // off disk originally
+  set<hobject_t> did;
+  for (list<pg_log_entry_t>::reverse_iterator i = log.log.rbegin();
+       i != log.log.rend();
+       ++i) {
+    if (i->version <= info.last_complete)
+      break;
+    if (i->soid > info.last_backfill ||
+       i->is_error() ||
+       did.find(i->soid) != did.end())
+      continue;
+    did.insert(i->soid);
+
+    bufferlist bv;
+    int r = store->getattr(
+       pg_coll,
+       ghobject_t(i->soid, ghobject_t::NO_GEN, info.pgid.shard),
+       OI_ATTR,
+       bv);
+    dout(20) << __func__ << " check for log entry: " << *i << " = " << r << dendl;
+
+    if (r >= 0) {
+      object_info_t oi(bv);
+      dout(20) << __func__ << " store version = " << oi.version << dendl;
+      if (oi.version < i->version) {
+       missing.add(i->soid, i->version, oi.version, i->is_delete());
+      }
+    } else {
+      missing.add(i->soid, i->version, eversion_t(), i->is_delete());
+    }
+  }
+
+  for (const auto& p : extra_missing) {
+    missing.add(p.first, p.second.need, p.second.have, p.second.is_delete());
+  }
+  rebuilt_missing_with_deletes = true;
+}
index 25a794605c148004b0873f1258c40cbb7cd20359..d910bc7f56ad7afaac0c40a64edbeea49c86cbd7 100644 (file)
@@ -705,6 +705,10 @@ public:
                        const pg_log_t &olog,
                        pg_missing_t& omissing, pg_shard_t from) const;
 
+  void rebuild_missing_set_with_deletes(ObjectStore *store,
+                                       coll_t pg_coll,
+                                       const pg_info_t &info);
+
 protected:
   static void split_by_object(
     mempool::osd_pglog::list<pg_log_entry_t> &entries,
index d8efc4f609fcfa649da26f3a6c3f51ba65f55539..dd6e4ef852d04d9c82dd5a28ddd7df3288293ae5 100644 (file)
@@ -10819,6 +10819,12 @@ void PrimaryLogPG::on_activate()
 
 void PrimaryLogPG::_on_new_interval()
 {
+  dout(20) << __func__ << "checking missing set deletes flag. missing = " << pg_log.get_missing() << dendl;
+  if (!pg_log.get_missing().may_include_deletes &&
+      get_osdmap()->test_flag(CEPH_OSDMAP_RECOVERY_DELETES)) {
+    pg_log.rebuild_missing_set_with_deletes(osd->store, coll, info);
+  }
+  assert(pg_log.get_missing().may_include_deletes == get_osdmap()->test_flag(CEPH_OSDMAP_RECOVERY_DELETES));
 }
 
 void PrimaryLogPG::on_change(ObjectStore::Transaction *t)