]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/Paxos: fix another uncommitted value corner case
authorSage Weil <sage@inktank.com>
Thu, 22 Aug 2013 22:54:48 +0000 (15:54 -0700)
committerSage Weil <sage@inktank.com>
Fri, 23 Aug 2013 17:38:53 +0000 (10:38 -0700)
It is possible that we begin the paxos recovery with an uncommitted
value for, say, commit 100.  During last/collect we discover 100 has been
committed already.  But also, another node provides an uncommitted value
for 101 with the same pn.  Currently, we refuse to learn it, because the
pn is not strictly > than our current uncommitted pn... even though it is
the next last_committed+1 value that we need.

There are two possible fixes here:

 - make this a >= as we can accept newer values from the same pn.
 - discard our uncommitted value metadata when we commit the value.

Let's do both!

Fixes: #6090
Signed-off-by: Sage Weil <sage@inktank.com>
src/mon/Paxos.cc

index 347810775c0465ee02c611862680438f632d8284..fa3e20898426b259153f9f8d0a5ec2527062d05c 100644 (file)
@@ -328,6 +328,15 @@ bool Paxos::store_state(MMonPaxos *m)
       // apply.
       decode_append_transaction(t, it->second);
     }
+
+    // discard obsolete uncommitted value?
+    if (uncommitted_v && uncommitted_v <= last_committed) {
+      dout(10) << " forgetting obsolete uncommitted value " << uncommitted_v
+              << " pn " << uncommitted_pn << dendl;
+      uncommitted_v = 0;
+      uncommitted_pn = 0;
+      uncommitted_value.clear();
+    }
   }
   if (!t.empty()) {
     dout(30) << __func__ << " transaction dump:\n";
@@ -425,7 +434,7 @@ void Paxos::handle_last(MMonPaxos *last)
 
     // did this person send back an accepted but uncommitted value?
     if (last->uncommitted_pn) {
-      if (last->uncommitted_pn > uncommitted_pn &&
+      if (last->uncommitted_pn >= uncommitted_pn &&
          last->last_committed >= last_committed &&
          last->last_committed + 1 >= uncommitted_v) {
        uncommitted_v = last->last_committed+1;