Skip to content

Commit adc4c91

Browse files
committed
Remove legacy MetaDataStateFormat (#31603)
Removes the legacy (pre-1.5) legacy MetaDataStateFormat.
1 parent 5b85062 commit adc4c91

File tree

90 files changed

+33
-108
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+33
-108
lines changed

server/src/main/java/org/elasticsearch/gateway/MetaDataStateFormat.java

Lines changed: 16 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,17 @@
2929
import org.apache.lucene.store.IndexInput;
3030
import org.apache.lucene.store.OutputStreamIndexOutput;
3131
import org.apache.lucene.store.SimpleFSDirectory;
32-
import org.elasticsearch.common.logging.Loggers;
33-
import org.elasticsearch.core.internal.io.IOUtils;
3432
import org.elasticsearch.ExceptionsHelper;
35-
import org.elasticsearch.common.bytes.BytesArray;
33+
import org.elasticsearch.common.logging.Loggers;
3634
import org.elasticsearch.common.lucene.store.IndexOutputOutputStream;
3735
import org.elasticsearch.common.lucene.store.InputStreamIndexInput;
3836
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
3937
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
4038
import org.elasticsearch.common.xcontent.XContentBuilder;
4139
import org.elasticsearch.common.xcontent.XContentFactory;
42-
import org.elasticsearch.common.xcontent.XContentHelper;
4340
import org.elasticsearch.common.xcontent.XContentParser;
4441
import org.elasticsearch.common.xcontent.XContentType;
42+
import org.elasticsearch.core.internal.io.IOUtils;
4543

4644
import java.io.FileNotFoundException;
4745
import java.io.IOException;
@@ -54,7 +52,6 @@
5452
import java.util.ArrayList;
5553
import java.util.Collection;
5654
import java.util.List;
57-
import java.util.function.Predicate;
5855
import java.util.regex.Matcher;
5956
import java.util.regex.Pattern;
6057
import java.util.stream.Collectors;
@@ -70,9 +67,8 @@ public abstract class MetaDataStateFormat<T> {
7067
public static final String STATE_FILE_EXTENSION = ".st";
7168

7269
private static final String STATE_FILE_CODEC = "state";
73-
private static final int MIN_COMPATIBLE_STATE_FILE_VERSION = 0;
70+
private static final int MIN_COMPATIBLE_STATE_FILE_VERSION = 1;
7471
private static final int STATE_FILE_VERSION = 1;
75-
private static final int STATE_FILE_VERSION_ES_2X_AND_BELOW = 0;
7672
private static final int BUFFER_SIZE = 4096;
7773
private final String prefix;
7874
private final Pattern stateFilePattern;
@@ -186,16 +182,11 @@ public final T read(NamedXContentRegistry namedXContentRegistry, Path file) thro
186182
try (IndexInput indexInput = dir.openInput(file.getFileName().toString(), IOContext.DEFAULT)) {
187183
// We checksum the entire file before we even go and parse it. If it's corrupted we barf right here.
188184
CodecUtil.checksumEntireFile(indexInput);
189-
final int fileVersion = CodecUtil.checkHeader(indexInput, STATE_FILE_CODEC, MIN_COMPATIBLE_STATE_FILE_VERSION,
190-
STATE_FILE_VERSION);
185+
CodecUtil.checkHeader(indexInput, STATE_FILE_CODEC, MIN_COMPATIBLE_STATE_FILE_VERSION, STATE_FILE_VERSION);
191186
final XContentType xContentType = XContentType.values()[indexInput.readInt()];
192187
if (xContentType != FORMAT) {
193188
throw new IllegalStateException("expected state in " + file + " to be " + FORMAT + " format but was " + xContentType);
194189
}
195-
if (fileVersion == STATE_FILE_VERSION_ES_2X_AND_BELOW) {
196-
// format version 0, wrote a version that always came from the content state file and was never used
197-
indexInput.readLong(); // version currently unused
198-
}
199190
long filePointer = indexInput.getFilePointer();
200191
long contentSize = indexInput.length() - CodecUtil.footerLength() - filePointer;
201192
try (IndexInput slice = indexInput.slice("state_xcontent", filePointer, contentSize)) {
@@ -263,10 +254,9 @@ long findMaxStateId(final String prefix, Path... locations) throws IOException {
263254
* @param dataLocations the data-locations to try.
264255
* @return the latest state or <code>null</code> if no state was found.
265256
*/
266-
public T loadLatestState(Logger logger, NamedXContentRegistry namedXContentRegistry, Path... dataLocations) throws IOException {
257+
public T loadLatestState(Logger logger, NamedXContentRegistry namedXContentRegistry, Path... dataLocations) throws IOException {
267258
List<PathAndStateId> files = new ArrayList<>();
268259
long maxStateId = -1;
269-
boolean maxStateIdIsLegacy = true;
270260
if (dataLocations != null) { // select all eligible files first
271261
for (Path dataLocation : dataLocations) {
272262
final Path stateDir = dataLocation.resolve(STATE_DIR_NAME);
@@ -280,9 +270,7 @@ public T loadLatestState(Logger logger, NamedXContentRegistry namedXContentRegi
280270
if (matcher.matches()) {
281271
final long stateId = Long.parseLong(matcher.group(1));
282272
maxStateId = Math.max(maxStateId, stateId);
283-
final boolean legacy = MetaDataStateFormat.STATE_FILE_EXTENSION.equals(matcher.group(2)) == false;
284-
maxStateIdIsLegacy &= legacy; // on purpose, see NOTE below
285-
PathAndStateId pav = new PathAndStateId(stateFile, stateId, legacy);
273+
PathAndStateId pav = new PathAndStateId(stateFile, stateId);
286274
logger.trace("found state file: {}", pav);
287275
files.add(pav);
288276
}
@@ -292,39 +280,19 @@ public T loadLatestState(Logger logger, NamedXContentRegistry namedXContentRegi
292280
}
293281
}
294282
}
295-
final List<Throwable> exceptions = new ArrayList<>();
296-
T state = null;
297283
// NOTE: we might have multiple version of the latest state if there are multiple data dirs.. for this case
298-
// we iterate only over the ones with the max version. If we have at least one state file that uses the
299-
// new format (ie. legacy == false) then we know that the latest version state ought to use this new format.
300-
// In case the state file with the latest version does not use the new format while older state files do,
301-
// the list below will be empty and loading the state will fail
284+
// we iterate only over the ones with the max version.
285+
long finalMaxStateId = maxStateId;
302286
Collection<PathAndStateId> pathAndStateIds = files
303287
.stream()
304-
.filter(new StateIdAndLegacyPredicate(maxStateId, maxStateIdIsLegacy))
288+
.filter(pathAndStateId -> pathAndStateId.id == finalMaxStateId)
305289
.collect(Collectors.toCollection(ArrayList::new));
306290

291+
final List<Throwable> exceptions = new ArrayList<>();
307292
for (PathAndStateId pathAndStateId : pathAndStateIds) {
308293
try {
309-
final Path stateFile = pathAndStateId.file;
310-
final long id = pathAndStateId.id;
311-
if (pathAndStateId.legacy) { // read the legacy format -- plain XContent
312-
final byte[] data = Files.readAllBytes(stateFile);
313-
if (data.length == 0) {
314-
logger.debug("{}: no data for [{}], ignoring...", prefix, stateFile.toAbsolutePath());
315-
continue;
316-
}
317-
try (XContentParser parser = XContentHelper
318-
.createParser(namedXContentRegistry, LoggingDeprecationHandler.INSTANCE, new BytesArray(data))) {
319-
state = fromXContent(parser);
320-
}
321-
if (state == null) {
322-
logger.debug("{}: no data for [{}], ignoring...", prefix, stateFile.toAbsolutePath());
323-
}
324-
} else {
325-
state = read(namedXContentRegistry, stateFile);
326-
logger.trace("state id [{}] read from [{}]", id, stateFile.getFileName());
327-
}
294+
T state = read(namedXContentRegistry, pathAndStateId.file);
295+
logger.trace("state id [{}] read from [{}]", pathAndStateId.id, pathAndStateId.file.getFileName());
328296
return state;
329297
} catch (Exception e) {
330298
exceptions.add(new IOException("failed to read " + pathAndStateId.toString(), e));
@@ -338,46 +306,24 @@ public T loadLatestState(Logger logger, NamedXContentRegistry namedXContentRegi
338306
// We have some state files but none of them gave us a usable state
339307
throw new IllegalStateException("Could not find a state file to recover from among " + files);
340308
}
341-
return state;
342-
}
343-
344-
/**
345-
* Filters out all {@link org.elasticsearch.gateway.MetaDataStateFormat.PathAndStateId} instances with a different id than
346-
* the given one.
347-
*/
348-
private static final class StateIdAndLegacyPredicate implements Predicate<PathAndStateId> {
349-
private final long id;
350-
private final boolean legacy;
351-
352-
StateIdAndLegacyPredicate(long id, boolean legacy) {
353-
this.id = id;
354-
this.legacy = legacy;
355-
}
356-
357-
@Override
358-
public boolean test(PathAndStateId input) {
359-
return input.id == id && input.legacy == legacy;
360-
}
309+
return null;
361310
}
362311

363312
/**
364-
* Internal struct-like class that holds the parsed state id, the file
365-
* and a flag if the file is a legacy state ie. pre 1.5
313+
* Internal struct-like class that holds the parsed state id and the file
366314
*/
367315
private static class PathAndStateId {
368316
final Path file;
369317
final long id;
370-
final boolean legacy;
371318

372-
private PathAndStateId(Path file, long id, boolean legacy) {
319+
private PathAndStateId(Path file, long id) {
373320
this.file = file;
374321
this.id = id;
375-
this.legacy = legacy;
376322
}
377323

378324
@Override
379325
public String toString() {
380-
return "[id:" + id + ", legacy:" + legacy + ", file:" + file.toAbsolutePath() + "]";
326+
return "[id:" + id + ", file:" + file.toAbsolutePath() + "]";
381327
}
382328
}
383329

server/src/test/java/org/elasticsearch/bwcompat/RecoveryWithUnsupportedIndicesIT.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,12 @@ protected Settings prepareBackwardsDataDir(Path backwardsIndex) throws IOExcepti
8181
return builder.build();
8282
}
8383

84-
public void testUpgradeStartClusterOn_0_20_6() throws Exception {
85-
String indexName = "unsupported-0.20.6";
84+
public void testUpgradeStartClusterOn_2_4_5() throws Exception {
85+
String indexName = "unsupported-2.4.5";
8686

8787
logger.info("Checking static index {}", indexName);
8888
Settings nodeSettings = prepareBackwardsDataDir(getBwcIndicesPath().resolve(indexName + ".zip"));
89-
try {
90-
internalCluster().startNode(nodeSettings);
91-
fail();
92-
} catch (Exception ex) {
93-
assertThat(ex.getCause().getCause().getMessage(), containsString(" was created before v2.0.0.beta1 and wasn't upgraded"));
94-
}
89+
assertThat(expectThrows(Exception.class, () -> internalCluster().startNode(nodeSettings))
90+
.getCause().getCause().getMessage(), containsString("Format version is not supported"));
9591
}
9692
}

server/src/test/java/org/elasticsearch/gateway/MetaDataStateFormatTests.java

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import org.elasticsearch.common.xcontent.ToXContent;
4040
import org.elasticsearch.common.xcontent.ToXContentFragment;
4141
import org.elasticsearch.common.xcontent.XContentBuilder;
42-
import org.elasticsearch.common.xcontent.XContentFactory;
4342
import org.elasticsearch.common.xcontent.XContentParser;
4443
import org.elasticsearch.index.Index;
4544
import org.elasticsearch.test.ESTestCase;
@@ -92,7 +91,7 @@ public MetaData fromXContent(XContentParser parser) throws IOException {
9291
Files.copy(resource, dst);
9392
MetaData read = format.read(xContentRegistry(), dst);
9493
assertThat(read, notNullValue());
95-
assertThat(read.clusterUUID(), equalTo("3O1tDF1IRB6fSJ-GrTMUtg"));
94+
assertThat(read.clusterUUID(), equalTo("y9XcwLJGTROoOEfixlRwfQ"));
9695
// indices are empty since they are serialized separately
9796
}
9897

@@ -237,7 +236,6 @@ public static void corruptFile(Path file, Logger logger) throws IOException {
237236
public void testLoadState() throws IOException {
238237
final Path[] dirs = new Path[randomIntBetween(1, 5)];
239238
int numStates = randomIntBetween(1, 5);
240-
int numLegacy = randomIntBetween(0, numStates);
241239
List<MetaData> meta = new ArrayList<>();
242240
for (int i = 0; i < numStates; i++) {
243241
meta.add(randomMeta());
@@ -247,20 +245,7 @@ public void testLoadState() throws IOException {
247245
for (int i = 0; i < dirs.length; i++) {
248246
dirs[i] = createTempDir();
249247
Files.createDirectories(dirs[i].resolve(MetaDataStateFormat.STATE_DIR_NAME));
250-
for (int j = 0; j < numLegacy; j++) {
251-
if (randomBoolean() && (j < numStates - 1 || dirs.length > 0 && i != 0)) {
252-
Path file = dirs[i].resolve(MetaDataStateFormat.STATE_DIR_NAME).resolve("global-"+j);
253-
Files.createFile(file); // randomly create 0-byte files -- there is extra logic to skip them
254-
} else {
255-
try (XContentBuilder xcontentBuilder = XContentFactory.contentBuilder(MetaDataStateFormat.FORMAT,
256-
Files.newOutputStream(dirs[i].resolve(MetaDataStateFormat.STATE_DIR_NAME).resolve("global-" + j)))) {
257-
xcontentBuilder.startObject();
258-
MetaData.Builder.toXContent(meta.get(j), xcontentBuilder, ToXContent.EMPTY_PARAMS);
259-
xcontentBuilder.endObject();
260-
}
261-
}
262-
}
263-
for (int j = numLegacy; j < numStates; j++) {
248+
for (int j = 0; j < numStates; j++) {
264249
format.write(meta.get(j), dirs[i]);
265250
if (randomBoolean() && (j < numStates - 1 || dirs.length > 0 && i != 0)) { // corrupt a file that we do not necessarily need here....
266251
Path file = dirs[i].resolve(MetaDataStateFormat.STATE_DIR_NAME).resolve("global-" + j + ".st");
@@ -290,20 +275,18 @@ public void testLoadState() throws IOException {
290275
assertThat(loadedMetaData.indexGraveyard(), equalTo(latestMetaData.indexGraveyard()));
291276

292277
// now corrupt all the latest ones and make sure we fail to load the state
293-
if (numStates > numLegacy) {
294-
for (int i = 0; i < dirs.length; i++) {
295-
Path file = dirs[i].resolve(MetaDataStateFormat.STATE_DIR_NAME).resolve("global-" + (numStates-1) + ".st");
296-
if (corruptedFiles.contains(file)) {
297-
continue;
298-
}
299-
MetaDataStateFormatTests.corruptFile(file, logger);
300-
}
301-
try {
302-
format.loadLatestState(logger, xContentRegistry(), dirList.toArray(new Path[0]));
303-
fail("latest version can not be read");
304-
} catch (ElasticsearchException ex) {
305-
assertThat(ExceptionsHelper.unwrap(ex, CorruptStateException.class), notNullValue());
278+
for (int i = 0; i < dirs.length; i++) {
279+
Path file = dirs[i].resolve(MetaDataStateFormat.STATE_DIR_NAME).resolve("global-" + (numStates-1) + ".st");
280+
if (corruptedFiles.contains(file)) {
281+
continue;
306282
}
283+
MetaDataStateFormatTests.corruptFile(file, logger);
284+
}
285+
try {
286+
format.loadLatestState(logger, xContentRegistry(), dirList.toArray(new Path[0]));
287+
fail("latest version can not be read");
288+
} catch (ElasticsearchException ex) {
289+
assertThat(ExceptionsHelper.unwrap(ex, CorruptStateException.class), notNullValue());
307290
}
308291
}
309292

-22.3 KB
Binary file not shown.
-203 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
-96.3 KB
Binary file not shown.
-91.3 KB
Binary file not shown.
-102 KB
Binary file not shown.

0 commit comments

Comments
 (0)