From 08571e01e86fa8bd4234a35987217806be979e7d Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 2 Feb 2023 14:40:48 +0800 Subject: [PATCH] mds: force replay sessionmap version 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 --- src/mds/journal.cc | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 0059c07c8ea7f..f8e3d802d4112 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -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); } } -- 2.39.5