]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
PGLog: track dirty_to and dirty_from for log
authorSamuel Just <sam.just@inktank.com>
Mon, 10 Jun 2013 22:42:19 +0000 (15:42 -0700)
committerSamuel Just <sam.just@inktank.com>
Mon, 17 Jun 2013 21:50:52 +0000 (14:50 -0700)
This allows the log to only write out/clear the keys
which have actually changed.

Signed-off-by: Samuel Just <sam.just@inktank.com>
src/osd/PGLog.cc
src/osd/PGLog.h

index 5995918dcbce63b7d600088e1faeb91dba0235f6..c7d8d0ea4061c52e7ea05a611d0d27a4b89fea6d 100644 (file)
@@ -526,23 +526,71 @@ void PGLog::merge_log(ObjectStore::Transaction& t,
   }
 }
 
+void PGLog::write_log(
+  ObjectStore::Transaction& t, const hobject_t &log_oid)
+{
+  if (dirty()) {
+    dout(10) << "write_log with: "
+            << "dirty_to: " << dirty_to
+            << ", dirty_from: " << dirty_from
+            << ", dirty_divergent_priors: " << dirty_divergent_priors
+            << dendl;
+    _write_log(t, log, log_oid, divergent_priors,
+              dirty_to,
+              dirty_from,
+              dirty_divergent_priors,
+              !touched_log);
+    undirty();
+  } else {
+    dout(10) << "log is not dirty" << dendl;
+  }
+}
+
 void PGLog::write_log(ObjectStore::Transaction& t, pg_log_t &log,
     const hobject_t &log_oid, map<eversion_t, hobject_t> &divergent_priors)
 {
-  //dout(10) << "write_log" << dendl;
-  t.remove(coll_t::META_COLL, log_oid);
-  t.touch(coll_t::META_COLL, log_oid);
+  _write_log(t, log, log_oid, divergent_priors, eversion_t::max(), eversion_t(),
+            true, true);
+}
+
+void PGLog::_write_log(
+  ObjectStore::Transaction& t, pg_log_t &log,
+  const hobject_t &log_oid, map<eversion_t, hobject_t> &divergent_priors,
+  eversion_t dirty_to,
+  eversion_t dirty_from,
+  bool dirty_divergent_priors,
+  bool touch_log
+  )
+{
+//dout(10) << "write_log, clearing up to " << dirty_to << dendl;
+  if (touch_log)
+    t.touch(coll_t(), log_oid);
+  t.omap_rmkeyrange(
+    coll_t(), log_oid,
+    eversion_t().get_key_name(), dirty_to.get_key_name());
+  if (dirty_to != eversion_t::max()) {
+    //   dout(10) << "write_log, clearing from " << dirty_from << dendl;
+    t.omap_rmkeyrange(
+      coll_t(), log_oid,
+      dirty_from.get_key_name(), eversion_t::max().get_key_name());
+  }
+
   map<string,bufferlist> keys;
   for (list<pg_log_entry_t>::iterator p = log.log.begin();
        p != log.log.end();
        ++p) {
-    bufferlist bl(sizeof(*p) * 2);
-    p->encode_with_checksum(bl);
-    keys[p->get_key_name()].claim(bl);
+    if ((p->version < dirty_to) || (p->version >= dirty_from)) {
+      bufferlist bl(sizeof(*p) * 2);
+      p->encode_with_checksum(bl);
+      keys[p->get_key_name()].claim(bl);
+    }
   }
-  //dout(10) << "write_log " << keys.size() << " keys" << dendl;
+//dout(10) << "write_log " << keys.size() << " keys" << dendl;
 
-  ::encode(divergent_priors, keys["divergent_priors"]);
+  if (dirty_divergent_priors) {
+    //dout(10) << "write_log: writing divergent_priors" << dendl;
+    ::encode(divergent_priors, keys["divergent_priors"]);
+  }
 
   t.omap_setkeys(coll_t::META_COLL, log_oid, keys);
 }
index 8587cdbf261a42691bf0f32902ad25e270ede7c4..9cf88c29c641b8ff0db6eba239d03fb955cac706 100644 (file)
@@ -147,10 +147,6 @@ struct PGLog {
   };
 
 
-  void add_divergent_prior(eversion_t version, hobject_t obj) {
-    divergent_priors.insert(make_pair(version, obj));
-  }
-
 protected:
   //////////////////// data members ////////////////////
 
@@ -158,7 +154,42 @@ protected:
   pg_missing_t     missing;
   IndexedLog  log;
 
+  /// Log is clean on [dirty_to, dirty_from)
+  bool touched_log;
+  eversion_t dirty_to;
+  eversion_t dirty_from;
+  bool dirty_divergent_priors;
+
+  void undirty() {
+    dirty_to = eversion_t();
+    dirty_from = eversion_t::max();
+    dirty_divergent_priors = false;
+    touched_log = true;
+  }
+  bool dirty() const {
+    return !touched_log ||
+      (dirty_to != eversion_t()) ||
+      (dirty_from != eversion_t::max()) ||
+      dirty_divergent_priors;
+  }
+  void mark_dirty_to(eversion_t to) {
+    if (to > dirty_to)
+      dirty_to = to;
+  }
+  void mark_dirty_from(eversion_t from) {
+    if (from < dirty_from)
+      dirty_from = from;
+  }
+  void add_divergent_prior(eversion_t version, hobject_t obj) {
+    divergent_priors.insert(make_pair(version, obj));
+    dirty_divergent_priors = true;
+  }
+
+
 public:
+  PGLog() :
+    touched_log(false), dirty_from(eversion_t::max()),
+    dirty_divergent_priors(false) {}
 
 
   void reset_backfill();
@@ -289,13 +320,20 @@ public:
                       pg_info_t &info, list<hobject_t>& remove_snap,
                       bool &dirty_log, bool &dirty_info, bool &dirty_big_info);
 
-  void write_log(ObjectStore::Transaction& t, const hobject_t &log_oid) {
-    write_log(t, log, log_oid, divergent_priors);
-  }
+  void write_log(ObjectStore::Transaction& t, const hobject_t &log_oid);
 
   static void write_log(ObjectStore::Transaction& t, pg_log_t &log,
     const hobject_t &log_oid, map<eversion_t, hobject_t> &divergent_priors);
 
+  static void _write_log(
+    ObjectStore::Transaction& t, pg_log_t &log,
+    const hobject_t &log_oid, map<eversion_t, hobject_t> &divergent_priors,
+    eversion_t dirty_to,
+    eversion_t dirty_from,
+    bool dirty_divergent_priors,
+    bool touch_log
+    );
+
   bool read_log(ObjectStore *store, coll_t coll, hobject_t log_oid,
                const pg_info_t &info, ostringstream &oss) {
     return read_log(store, coll, log_oid, info, divergent_priors,