summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Just <sam.just@inktank.com>2013-06-10 15:42:19 -0700
committerSamuel Just <sam.just@inktank.com>2013-06-17 14:50:52 -0700
commitd77c4ffa5354e83328c7079ee4b4b63aec8011a3 (patch)
treed85757652cdfc3a9f44b812b15be7444806c85ff
parentfb88873cd56ccd6bd8e51acc9a0691d51fdabdfc (diff)
downloadceph-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.cc64
-rw-r--r--src/osd/PGLog.h52
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,