diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 3ddcb951284a..69f3334ad988 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -122,6 +122,8 @@ Other Applications using SecurityManager now need to grant SerializablePermission("serialFilter") to the analysis-smartcn module. (Uwe Schindler, Isaac David) +* GITHUB#15431: Index open performs version check on each segment, ignores indexCreatedVersionMajor (Rahul Goswami, Mike Sokolov) + Build --------------------- * Upgrade forbiddenapis to version 3.10. (Uwe Schindler) diff --git a/lucene/backward-codecs/src/test/org/apache/lucene/backward_index/TestBasicBackwardsCompatibility.java b/lucene/backward-codecs/src/test/org/apache/lucene/backward_index/TestBasicBackwardsCompatibility.java index cf50b9e1526d..c2aa65cced9c 100644 --- a/lucene/backward-codecs/src/test/org/apache/lucene/backward_index/TestBasicBackwardsCompatibility.java +++ b/lucene/backward-codecs/src/test/org/apache/lucene/backward_index/TestBasicBackwardsCompatibility.java @@ -861,7 +861,10 @@ public void testFailOpenOldIndex() throws IOException { () -> StandardDirectoryReader.open(commit, Version.LATEST.major, null)); assertTrue( ex.getMessage() - .contains("only supports reading from version " + Version.LATEST.major + " upwards.")); + .contains( + "This Lucene version only supports indexes with major version " + + Version.LATEST.major + + " or later")); // now open with allowed min version StandardDirectoryReader.open(commit, Version.MIN_SUPPORTED_MAJOR, null).close(); } diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java b/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java index 3b65e1cbff8d..5cd4551f6ced 100644 --- a/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java +++ b/lucene/core/src/java/org/apache/lucene/index/SegmentInfos.java @@ -346,25 +346,12 @@ public static final SegmentInfos readCommit( input); } - if (indexCreatedVersion < minSupportedMajorVersion) { - throw new IndexFormatTooOldException( - input, - "This index was initially created with Lucene " - + indexCreatedVersion - + ".x while the current version is " - + Version.LATEST - + " and Lucene only supports reading" - + (minSupportedMajorVersion == Version.MIN_SUPPORTED_MAJOR - ? " the current and previous major versions" - : " from version " + minSupportedMajorVersion + " upwards")); - } - SegmentInfos infos = new SegmentInfos(indexCreatedVersion); infos.id = id; infos.generation = generation; infos.lastGeneration = generation; infos.luceneVersion = luceneVersion; - parseSegmentInfos(directory, input, infos, format); + parseSegmentInfos(directory, input, infos, format, minSupportedMajorVersion); return infos; } catch (Throwable t) { @@ -380,7 +367,12 @@ public static final SegmentInfos readCommit( } private static void parseSegmentInfos( - Directory directory, DataInput input, SegmentInfos infos, int format) throws IOException { + Directory directory, + DataInput input, + SegmentInfos infos, + int format, + int minSupportedMajorVersion) + throws IOException { infos.version = CodecUtil.readBELong(input); // System.out.println("READ sis version=" + infos.version); infos.counter = input.readVLong(); @@ -397,6 +389,7 @@ private static void parseSegmentInfos( } long totalDocs = 0; + for (int seg = 0; seg < numSegments; seg++) { String segName = input.readString(); byte[] segmentID = new byte[StringHelper.ID_LENGTH]; @@ -490,6 +483,30 @@ private static void parseSegmentInfos( + infos.indexCreatedVersionMajor, input); } + + int createdOrSegmentMinVersion = + info.getMinVersion() == null + ? infos.indexCreatedVersionMajor + : info.getMinVersion().major; + + // version >=7 are expected to record minVersion + if (info.getMinVersion() == null || info.getMinVersion().major < minSupportedMajorVersion) { + throw new IndexFormatTooOldException( + input, + "Index has segments derived from Lucene version " + + createdOrSegmentMinVersion + + ".x and is not supported by Lucene " + + Version.LATEST + + ". This Lucene version only supports indexes with major version " + + minSupportedMajorVersion + + " or later (found: " + + createdOrSegmentMinVersion + + ", minimum supported: " + + minSupportedMajorVersion + + "). To resolve this issue re-index your data using Lucene " + + minSupportedMajorVersion + + ".x or later."); + } } infos.userData = input.readMapOfStrings(); @@ -512,11 +529,13 @@ private static Codec readCodec(DataInput input) throws IOException { } catch (IllegalArgumentException e) { // maybe it's an old default codec that moved if (name.startsWith("Lucene")) { - throw new IllegalArgumentException( + throw new IndexFormatTooOldException( + input, "Could not load codec '" + name - + "'. Did you forget to add lucene-backward-codecs.jar?", - e); + + "'. " + + e.getMessage() + + ". Did you forget to add lucene-backward-codecs.jar?"); } throw e; }