From 6ad9fe17a674ba65bbeb4052cb1ac47f3113e7bf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 4 Jul 2013 19:33:06 -0700 Subject: [PATCH] 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 --- src/mon/Monitor.cc | 30 ++++++++++++++++++++++++------ 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 bb328325f109d..22c6d58100c6d 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 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 e6bdc8f2af494..6cc4382d5ee2f 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(); -- 2.39.5