diff --git a/modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainResponseTests.java b/modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainResponseTests.java index 3dfcac3cdecae..dc61abf33e286 100644 --- a/modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainResponseTests.java +++ b/modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainResponseTests.java @@ -66,7 +66,7 @@ public void testToXContent() throws IOException { build.date(), build.isSnapshot(), indexVersion.luceneVersion().toString(), - version.minimumCompatibilityVersion().toString(), + build.minWireCompatVersion(), Build.minimumCompatString(IndexVersion.MINIMUM_COMPATIBLE) ) ), diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java index 79c6dca764250..41be7f2dea98e 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/TestSystemIndexDescriptor.java @@ -8,6 +8,7 @@ package org.elasticsearch.indices; +import org.elasticsearch.Build; import org.elasticsearch.Version; import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.Strings; @@ -51,7 +52,7 @@ public class TestSystemIndexDescriptor extends SystemIndexDescriptor { 0, "version", "stack", - Version.CURRENT.minimumCompatibilityVersion(), + Version.fromString(Build.current().minWireCompatVersion()), Type.INTERNAL_MANAGED, List.of(), List.of(), @@ -72,7 +73,7 @@ public class TestSystemIndexDescriptor extends SystemIndexDescriptor { 0, "version", "stack", - Version.CURRENT.minimumCompatibilityVersion(), + Version.fromString(Build.current().minWireCompatVersion()), Type.INTERNAL_MANAGED, List.of(), List.of(), diff --git a/server/src/main/java/org/elasticsearch/env/NodeEnvironment.java b/server/src/main/java/org/elasticsearch/env/NodeEnvironment.java index 673484ac94c77..943cb06e9c6b5 100644 --- a/server/src/main/java/org/elasticsearch/env/NodeEnvironment.java +++ b/server/src/main/java/org/elasticsearch/env/NodeEnvironment.java @@ -87,6 +87,8 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -525,19 +527,21 @@ static void checkForIndexCompatibility(Logger logger, DataPath... dataPaths) thr logger.info("oldest index version recorded in NodeMetadata {}", metadata.oldestIndexVersion()); if (metadata.oldestIndexVersion().isLegacyIndexVersion()) { + + String bestDowngradeVersion = getBestDowngradeVersion(metadata.previousNodeVersion().toString()); throw new IllegalStateException( "Cannot start this node because it holds metadata for indices with version [" + metadata.oldestIndexVersion() + "] with which this node of version [" + Build.current().version() + "] is incompatible. Revert this node to version [" - + Version.max(Version.CURRENT.minimumCompatibilityVersion(), metadata.previousNodeVersion()) + + bestDowngradeVersion + "] and delete any indices with versions earlier than [" + IndexVersion.MINIMUM_COMPATIBLE + "] before upgrading to version [" + Build.current().version() + "]. If all such indices have already been deleted, revert this node to version [" - + Version.max(Version.CURRENT.minimumCompatibilityVersion(), metadata.previousNodeVersion()) + + bestDowngradeVersion + "] and wait for it to join the cluster to clean up any older indices from its metadata." ); } @@ -1505,4 +1509,32 @@ private static void tryWriteTempFile(Path path) throws IOException { } } } + + /** + * Get a useful version string to direct a user's downgrade operation + * + *
If a user is trying to install 8.0 but has incompatible indices, the user should
+ * downgrade to 7.17.x. We return 7.17.0, unless the user is trying to upgrade from
+ * a 7.17.x release, in which case we return the last installed version.
+ * @return Version to downgrade to
+ */
+ // visible for testing
+ static String getBestDowngradeVersion(String previousNodeVersion) {
+ // this method should only be called in the context of an upgrade to 8.x
+ assert Build.current().version().startsWith("9.") == false;
+ Pattern pattern = Pattern.compile("^7\\.(\\d+)\\.\\d+$");
+ Matcher matcher = pattern.matcher(previousNodeVersion);
+ if (matcher.matches()) {
+ try {
+ int minorVersion = Integer.parseInt(matcher.group(1));
+ if (minorVersion >= 17) {
+ return previousNodeVersion;
+ }
+ } catch (NumberFormatException e) {
+ // continue and return default
+ }
+ }
+ return "7.17.0";
+ }
+
}
diff --git a/server/src/main/java/org/elasticsearch/env/NodeMetadata.java b/server/src/main/java/org/elasticsearch/env/NodeMetadata.java
index ecc29e793f331..37dd01733e664 100644
--- a/server/src/main/java/org/elasticsearch/env/NodeMetadata.java
+++ b/server/src/main/java/org/elasticsearch/env/NodeMetadata.java
@@ -113,7 +113,7 @@ public void verifyUpgradeToCurrentVersion() {
assert (nodeVersion.equals(Version.V_EMPTY) == false) || (Version.CURRENT.major <= Version.V_7_0_0.major + 1)
: "version is required in the node metadata from v9 onwards";
- if (nodeVersion.before(Version.CURRENT.minimumCompatibilityVersion())) {
+ if (NodeMetadata.isNodeVersionWireCompatible(nodeVersion.toString()) == false) {
throw new IllegalStateException(
"cannot upgrade a node from version ["
+ nodeVersion
@@ -220,4 +220,21 @@ public NodeMetadata fromXContent(XContentParser parser) throws IOException {
}
public static final MetadataStateFormat