]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: force replay sessionmap version 49970/head
authorXiubo Li <xiubli@redhat.com>
Thu, 2 Feb 2023 06:40:48 +0000 (14:40 +0800)
committerXiubo Li <xiubli@redhat.com>
Tue, 14 Feb 2023 01:13:08 +0000 (09:13 +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>
src/mds/journal.cc

index 0059c07c8ea7fdf53636f6bca5e3f10c8cff68a1..f8e3d802d4112a37b383a3a03edf16fdcf76946a 100644 (file)
@@ -1572,24 +1572,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;
@@ -1609,7 +1609,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)
@@ -1618,13 +1617,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);
     }
   }