]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-monstore-tool: use a large enough paxos/{first,last}_committed
authorKefu Chai <kchai@redhat.com>
Tue, 9 Apr 2019 14:07:02 +0000 (22:07 +0800)
committerKefu Chai <kchai@redhat.com>
Wed, 16 Jun 2021 02:12:10 +0000 (10:12 +0800)
so the rebuild paxos transaction won't be overwritten by the ones
created before recovery completes.

when the quorum is recovering, the leader will collect the paxos
transactions from peons. if the quorum accept the proposal for setting
the fingerprint, the peon will update the monitor with the paxos
transaction with a newer "last_committed" than the one created using
update_paxos() in ceph_monstore_tool.cc. the latter "last_committed" is
always 0.

so, to avoid this extra paxos proposal obsoleting the "rebuilding" paxos
transaction, we use a large enough number for {first,last}_committed.

Fixes: http://tracker.ceph.com/issues/38219
Signed-off-by: Kefu Chai <kchai@redhat.com>
(cherry picked from commit 5475ef7843ab4021eddee60c2789b81d616383e9)

src/tools/ceph_monstore_tool.cc

index 9ff08f3237d9b8c3414f20be00212801cda5d241..43f2e932325475ebe5f6a28a3a8c01d5bb7fe99f 100644 (file)
@@ -629,6 +629,24 @@ static int update_mgrmap(MonitorDBStore& st)
 
 static int update_paxos(MonitorDBStore& st)
 {
+  const string prefix("paxos");
+  // a large enough version greater than the maximum possible `last_committed`
+  // that could be replied by the peons when the leader is collecting paxos
+  // transactions during recovery
+  constexpr version_t first_committed = 0x42;
+  constexpr version_t last_committed = first_committed;
+  for (version_t v = first_committed; v < last_committed + 1; v++) {
+    auto t = make_shared<MonitorDBStore::Transaction>();
+    if (v == first_committed) {
+      t->put(prefix, "first_committed", v);
+    }
+    bufferlist proposal;
+    MonitorDBStore::Transaction empty_txn;
+    empty_txn.encode(proposal);
+    t->put(prefix, v, proposal);
+    t->put(prefix, "last_committed", v);
+    st.apply_transaction(t);
+  }
   // build a pending paxos proposal from all non-permanent k/v pairs. once the
   // proposal is committed, it will gets applied. on the sync provider side, it
   // will be a no-op, but on its peers, the paxos commit will help to build up
@@ -647,11 +665,8 @@ static int update_paxos(MonitorDBStore& st)
     }
     t.encode(pending_proposal);
   }
-  const string prefix("paxos");
+  auto pending_v = last_committed + 1;
   auto t = make_shared<MonitorDBStore::Transaction>();
-  t->put(prefix, "first_committed", 0);
-  t->put(prefix, "last_committed", 0);
-  auto pending_v = 1;
   t->put(prefix, pending_v, pending_proposal);
   t->put(prefix, "pending_v", pending_v);
   t->put(prefix, "pending_pn", 400);