]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: force replay sessionmap version 50725/head
authorXiubo Li <xiubli@redhat.com>
Thu, 2 Feb 2023 06:40:48 +0000 (14:40 +0800)
committerXiubo Li <xiubli@redhat.com>
Wed, 29 Mar 2023 03:09:06 +0000 (11:09 +0800)
When expiring the MDLog Segments it will persist the sessionmap, but
in case the number of Segments doesn't reach up to the max segment
threshold then the expiry may not happen.

So if there is a MDS failover then the sessionmap won't be persistent
and cannot be replayed by the standby MDS when it is starting. We
should just force replay the sessionmap version just the way inotable
does.

Fixes: https://tracker.ceph.com/issues/58489
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit 08571e01e86fa8bd4234a35987217806be979e7d)

src/mds/journal.cc

index 09c39d15d81173f64c557d09094bd03202f2c442..b2ceecd054d9373d469f5af2560821471311dab7 100644 (file)
@@ -1565,24 +1565,24 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDPeerUpdate *peerup)
       if (preallocated_inos.size())
        mds->inotable->replay_alloc_ids(preallocated_inos);
 
-      // [repair bad inotable updates]
+      // repair inotable updates in case inotable wasn't persist in time
       if (inotablev > mds->inotable->get_version()) {
-       mds->clog->error() << "journal replay inotablev mismatch "
-           << mds->inotable->get_version() << " -> " << inotablev;
-       mds->inotable->force_replay_version(inotablev);
+        mds->clog->error() << "journal replay inotablev mismatch "
+            << mds->inotable->get_version() << " -> " << inotablev
+            << ", will force replay it.";
+        mds->inotable->force_replay_version(inotablev);
       }
 
       ceph_assert(inotablev == mds->inotable->get_version());
     }
   }
   if (sessionmapv) {
-    unsigned diff = (used_preallocated_ino && !preallocated_inos.empty()) ? 2 : 1;
     if (mds->sessionmap.get_version() >= sessionmapv) {
       dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
               << " <= table " << mds->sessionmap.get_version() << dendl;
-    } else if (mds->sessionmap.get_version() + diff == sessionmapv) {
+    } else {
       dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
-              << " - " << diff << " == table " << mds->sessionmap.get_version()
+              << ", table " << mds->sessionmap.get_version()
               << " prealloc " << preallocated_inos
               << " used " << used_preallocated_ino
               << dendl;
@@ -1602,7 +1602,6 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDPeerUpdate *peerup)
          session->info.prealloc_inos.insert(preallocated_inos);
           mds->sessionmap.replay_dirty_session(session);
        }
-
       } else {
        dout(10) << "EMetaBlob.replay no session for " << client_name << dendl;
        if (used_preallocated_ino)
@@ -1611,13 +1610,19 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDPeerUpdate *peerup)
        if (!preallocated_inos.empty())
          mds->sessionmap.replay_advance_version();
       }
+
+      // repair sessionmap updates in case sessionmap wasn't persist in time
+      if (sessionmapv > mds->sessionmap.get_version()) {
+        mds->clog->error() << "EMetaBlob.replay sessionmapv mismatch "
+            << sessionmapv << " -> " << mds->sessionmap.get_version()
+            << ", will force replay it.";
+        if (g_conf()->mds_wipe_sessions) {
+          mds->sessionmap.wipe();
+        }
+        // force replay sessionmap version
+        mds->sessionmap.set_version(sessionmapv);
+      }
       ceph_assert(sessionmapv == mds->sessionmap.get_version());
-    } else {
-      mds->clog->error() << "EMetaBlob.replay sessionmap v " << sessionmapv
-                        << " - " << diff << " > table " << mds->sessionmap.get_version();
-      ceph_assert(g_conf()->mds_wipe_sessions);
-      mds->sessionmap.wipe();
-      mds->sessionmap.set_version(sessionmapv);
     }
   }