diff options
author | Samuel Just <sam.just@inktank.com> | 2013-06-10 15:42:19 -0700 |
---|---|---|
committer | Samuel Just <sam.just@inktank.com> | 2013-06-17 14:50:52 -0700 |
commit | d77c4ffa5354e83328c7079ee4b4b63aec8011a3 (patch) | |
tree | d85757652cdfc3a9f44b812b15be7444806c85ff | |
parent | fb88873cd56ccd6bd8e51acc9a0691d51fdabdfc (diff) | |
download | ceph-d77c4ffa5354e83328c7079ee4b4b63aec8011a3.tar.gz |
PGLog: track dirty_to and dirty_from for log
This allows the log to only write out/clear the keys
which have actually changed.
Signed-off-by: Samuel Just <sam.just@inktank.com>
-rw-r--r-- | src/osd/PGLog.cc | 64 | ||||
-rw-r--r-- | src/osd/PGLog.h | 52 |
2 files changed, 101 insertions, 15 deletions
diff --git a/src/osd/PGLog.cc b/src/osd/PGLog.cc index 5995918dcbc..c7d8d0ea406 100644 --- a/src/osd/PGLog.cc +++ b/src/osd/PGLog.cc @@ -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); } diff --git a/src/osd/PGLog.h b/src/osd/PGLog.h index 8587cdbf261..9cf88c29c64 100644 --- a/src/osd/PGLog.h +++ b/src/osd/PGLog.h @@ -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, |