diff options
author | Sage Weil <sage@inktank.com> | 2013-07-04 19:33:06 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-07-05 10:07:15 -0700 |
commit | 6ad9fe17a674ba65bbeb4052cb1ac47f3113e7bf (patch) | |
tree | e93b42b90bb90a677a9d31eecbb49b0c8f80c6d1 | |
parent | c5812b1c893305a7d20f9eaec2695c8b1691f0c9 (diff) | |
download | ceph-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.cc | 30 | ||||
-rw-r--r-- | src/mon/Monitor.h | 3 |
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(); |