summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-07-04 19:33:06 -0700
committerSage Weil <sage@inktank.com>2013-07-05 10:07:15 -0700
commit6ad9fe17a674ba65bbeb4052cb1ac47f3113e7bf (patch)
treee93b42b90bb90a677a9d31eecbb49b0c8f80c6d1
parentc5812b1c893305a7d20f9eaec2695c8b1691f0c9 (diff)
downloadceph-6ad9fe17a674ba65bbeb4052cb1ac47f3113e7bf.tar.gz
mon/Paxos: fix sync restart
If we have a sync going, and an election intervenes, the client will try to continue by sending a new start_chunks request. In order to ensure that we get all of the paxos commits from our original starting point (and thus properly update the keys from which they started), only pay attention if they *also* send their current last_committed version. Otherwise, start them at the beginning. Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/mon/Monitor.cc30
-rw-r--r--src/mon/Monitor.h3
2 files changed, 24 insertions, 9 deletions
diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc
index bb328325f10..22c6d58100c 100644
--- a/src/mon/Monitor.cc
+++ b/src/mon/Monitor.cc
@@ -1227,14 +1227,30 @@ void Monitor::handle_sync_start_chunks(MMonSync *m)
}
SyncEntity sync = get_sync_entity(other, this);
- sync->version = paxos->get_version();
if (!m->last_key.first.empty() && !m->last_key.second.empty()) {
- sync->last_received_key = m->last_key;
- dout(10) << __func__ << " set last received key to ("
- << sync->last_received_key.first << ","
- << sync->last_received_key.second << ")" << dendl;
+ if (m->version == 0) {
+ // uh-oh; we can't do this safely without a proper version marker
+ // because we don't know what paxos commits they got from the
+ // previous keys (if any!), and we may miss some.
+ dout(1) << __func__ << " got mid-sync start_chunks from " << other
+ << " without version marker; ignoring last_received_key marker" << dendl;
+ sync->version = paxos->get_version();
+ } else {
+ sync->version = m->version;
+ sync->last_received_key = m->last_key;
+ dout(10) << __func__ << " set last received key to ("
+ << sync->last_received_key.first << ","
+ << sync->last_received_key.second << ")" << dendl;
+ }
+ } else {
+ sync->version = paxos->get_version();
}
+ dout(10) << __func__ << " version " << sync->version
+ << " last received key ("
+ << sync->last_received_key.first << ","
+ << sync->last_received_key.second << ")"
+ << dendl;
sync->sync_init();
@@ -1550,8 +1566,10 @@ void Monitor::sync_start_chunks(SyncEntity provider)
g_conf->mon_sync_timeout);
MMonSync *msg = new MMonSync(MMonSync::OP_START_CHUNKS);
pair<string,string> last_key = provider->last_received_key;
- if (!last_key.first.empty() && !last_key.second.empty())
+ if (!last_key.first.empty() && !last_key.second.empty()) {
msg->last_key = last_key;
+ msg->version = store->get("paxos", "last_committed");
+ }
assert(g_conf->mon_sync_requester_kill_at != 4);
messenger->send_message(msg, provider->entity);
diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h
index e6bdc8f2af4..6cc4382d5ee 100644
--- a/src/mon/Monitor.h
+++ b/src/mon/Monitor.h
@@ -604,9 +604,6 @@ private:
string prefix("paxos");
paxos_synchronizer = mon->store->get_synchronizer(prefix);
- version = mon->paxos->get_version();
- generic_dout(10) << __func__ << " version " << version << dendl;
-
synchronizer = mon->store->get_synchronizer(last_received_key,
sync_targets);
sync_update();