Skip to content

Commit b4edc3d

Browse files
authored
Remove loading on-disk cluster metadata from the manifest file (#114698)
Since metadata storage was moved to Lucene in #50907 (7.16.0), we shouldn't encounter any on-disk global metadata files, so we can remove support for loading them.
1 parent 79cfcec commit b4edc3d

File tree

6 files changed

+1
-332
lines changed

6 files changed

+1
-332
lines changed

server/src/internalClusterTest/java/org/elasticsearch/gateway/GatewayIndexStateIT.java

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.elasticsearch.action.support.ActiveShardCount;
1818
import org.elasticsearch.client.internal.Client;
1919
import org.elasticsearch.cluster.ClusterState;
20-
import org.elasticsearch.cluster.coordination.CoordinationMetadata;
2120
import org.elasticsearch.cluster.metadata.IndexGraveyard;
2221
import org.elasticsearch.cluster.metadata.IndexMetadata;
2322
import org.elasticsearch.cluster.metadata.MappingMetadata;
@@ -27,14 +26,9 @@
2726
import org.elasticsearch.cluster.routing.RoutingTable;
2827
import org.elasticsearch.cluster.routing.ShardRoutingState;
2928
import org.elasticsearch.cluster.routing.UnassignedInfo;
30-
import org.elasticsearch.cluster.service.ClusterService;
3129
import org.elasticsearch.common.Priority;
3230
import org.elasticsearch.common.settings.Settings;
33-
import org.elasticsearch.core.CheckedConsumer;
34-
import org.elasticsearch.core.IOUtils;
35-
import org.elasticsearch.env.BuildVersion;
3631
import org.elasticsearch.env.NodeEnvironment;
37-
import org.elasticsearch.env.NodeMetadata;
3832
import org.elasticsearch.index.IndexVersions;
3933
import org.elasticsearch.index.mapper.MapperParsingException;
4034
import org.elasticsearch.indices.IndexClosedException;
@@ -46,21 +40,15 @@
4640
import org.elasticsearch.xcontent.XContentFactory;
4741

4842
import java.io.IOException;
49-
import java.nio.file.Path;
5043
import java.util.List;
51-
import java.util.Map;
5244
import java.util.concurrent.TimeUnit;
53-
import java.util.function.Function;
54-
import java.util.stream.Collectors;
55-
import java.util.stream.Stream;
5645

5746
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
5847
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
5948
import static org.elasticsearch.test.NodeRoles.nonDataNode;
6049
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
6150
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
6251
import static org.hamcrest.Matchers.containsString;
63-
import static org.hamcrest.Matchers.empty;
6452
import static org.hamcrest.Matchers.equalTo;
6553
import static org.hamcrest.Matchers.greaterThan;
6654
import static org.hamcrest.Matchers.notNullValue;
@@ -545,52 +533,4 @@ public void testArchiveBrokenClusterSettings() throws Exception {
545533
assertHitCount(prepareSearch().setQuery(matchAllQuery()), 1L);
546534
}
547535

548-
public void testHalfDeletedIndexImport() throws Exception {
549-
// It's possible for a 6.x node to add a tombstone for an index but not actually delete the index metadata from disk since that
550-
// deletion is slightly deferred and may race against the node being shut down; if you upgrade to 7.x when in this state then the
551-
// node won't start.
552-
553-
final String nodeName = internalCluster().startNode();
554-
createIndex("test", 1, 0);
555-
ensureGreen("test");
556-
557-
final Metadata metadata = internalCluster().getInstance(ClusterService.class).state().metadata();
558-
final Path[] paths = internalCluster().getInstance(NodeEnvironment.class).nodeDataPaths();
559-
final String nodeId = clusterAdmin().prepareNodesInfo(nodeName).clear().get().getNodes().get(0).getNode().getId();
560-
561-
writeBrokenMeta(nodeEnvironment -> {
562-
for (final Path path : paths) {
563-
IOUtils.rm(path.resolve(PersistedClusterStateService.METADATA_DIRECTORY_NAME));
564-
}
565-
MetaStateWriterUtils.writeGlobalState(
566-
nodeEnvironment,
567-
"test",
568-
Metadata.builder(metadata)
569-
// we remove the manifest file, resetting the term and making this look like an upgrade from 6.x, so must also reset the
570-
// term in the coordination metadata
571-
.coordinationMetadata(CoordinationMetadata.builder(metadata.coordinationMetadata()).term(0L).build())
572-
// add a tombstone but do not delete the index metadata from disk
573-
.putCustom(IndexGraveyard.TYPE, IndexGraveyard.builder().addTombstone(metadata.index("test").getIndex()).build())
574-
.build()
575-
);
576-
NodeMetadata.FORMAT.writeAndCleanup(new NodeMetadata(nodeId, BuildVersion.current(), metadata.oldestIndexVersion()), paths);
577-
});
578-
579-
ensureGreen();
580-
581-
assertBusy(() -> assertThat(internalCluster().getInstance(NodeEnvironment.class).availableIndexFolders(), empty()));
582-
}
583-
584-
private void writeBrokenMeta(CheckedConsumer<NodeEnvironment, IOException> writer) throws Exception {
585-
Map<String, NodeEnvironment> nodeEnvironments = Stream.of(internalCluster().getNodeNames())
586-
.collect(Collectors.toMap(Function.identity(), nodeName -> internalCluster().getInstance(NodeEnvironment.class, nodeName)));
587-
internalCluster().fullRestart(new RestartCallback() {
588-
@Override
589-
public Settings onNodeStopped(String nodeName) throws Exception {
590-
final NodeEnvironment nodeEnvironment = nodeEnvironments.get(nodeName);
591-
writer.accept(nodeEnvironment);
592-
return super.onNodeStopped(nodeName);
593-
}
594-
});
595-
}
596536
}

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

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.elasticsearch.cluster.metadata.IndexMetadata;
2424
import org.elasticsearch.cluster.metadata.IndexMetadataVerifier;
2525
import org.elasticsearch.cluster.metadata.IndexTemplateMetadata;
26-
import org.elasticsearch.cluster.metadata.Manifest;
2726
import org.elasticsearch.cluster.metadata.Metadata;
2827
import org.elasticsearch.cluster.node.DiscoveryNode;
2928
import org.elasticsearch.cluster.service.ClusterService;
@@ -33,8 +32,6 @@
3332
import org.elasticsearch.common.util.concurrent.EsExecutors;
3433
import org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor;
3534
import org.elasticsearch.core.IOUtils;
36-
import org.elasticsearch.core.Tuple;
37-
import org.elasticsearch.core.UpdateForV9;
3835
import org.elasticsearch.env.BuildVersion;
3936
import org.elasticsearch.env.NodeMetadata;
4037
import org.elasticsearch.index.IndexVersions;
@@ -185,16 +182,6 @@ private PersistedState createOnDiskPersistedState(
185182
long lastAcceptedVersion = onDiskState.lastAcceptedVersion;
186183
long currentTerm = onDiskState.currentTerm;
187184

188-
if (onDiskState.empty()) {
189-
@UpdateForV9(owner = UpdateForV9.Owner.DISTRIBUTED_COORDINATION) // legacy metadata loader is not needed anymore from v9 onwards
190-
final Tuple<Manifest, Metadata> legacyState = metaStateService.loadFullState();
191-
if (legacyState.v1().isEmpty() == false) {
192-
metadata = legacyState.v2();
193-
lastAcceptedVersion = legacyState.v1().clusterStateVersion();
194-
currentTerm = legacyState.v1().currentTerm();
195-
}
196-
}
197-
198185
PersistedState persistedState = null;
199186
boolean success = false;
200187
try {

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

Lines changed: 1 addition & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,17 @@
1212
import org.apache.logging.log4j.LogManager;
1313
import org.apache.logging.log4j.Logger;
1414
import org.elasticsearch.Version;
15-
import org.elasticsearch.cluster.metadata.IndexGraveyard;
1615
import org.elasticsearch.cluster.metadata.IndexMetadata;
1716
import org.elasticsearch.cluster.metadata.Manifest;
1817
import org.elasticsearch.cluster.metadata.Metadata;
1918
import org.elasticsearch.core.Nullable;
20-
import org.elasticsearch.core.Tuple;
21-
import org.elasticsearch.core.UpdateForV9;
2219
import org.elasticsearch.env.NodeEnvironment;
2320
import org.elasticsearch.index.Index;
2421
import org.elasticsearch.xcontent.NamedXContentRegistry;
2522

2623
import java.io.IOException;
2724
import java.util.ArrayList;
28-
import java.util.HashMap;
2925
import java.util.List;
30-
import java.util.Map;
3126
import java.util.function.Predicate;
3227

3328
/**
@@ -45,118 +40,6 @@ public MetaStateService(NodeEnvironment nodeEnv, NamedXContentRegistry namedXCon
4540
this.namedXContentRegistry = namedXContentRegistry;
4641
}
4742

48-
/**
49-
* Loads the full state, which includes both the global state and all the indices meta data. <br>
50-
* When loading, manifest file is consulted (represented by {@link Manifest} class), to load proper generations. <br>
51-
* If there is no manifest file on disk, this method fallbacks to BWC mode, where latest generation of global and indices
52-
* metadata is loaded. Please note that currently there is no way to distinguish between manifest file being removed and manifest
53-
* file was not yet created. It means that this method always fallbacks to BWC mode, if there is no manifest file.
54-
*
55-
* @return tuple of {@link Manifest} and {@link Metadata} with global metadata and indices metadata. If there is no state on disk,
56-
* meta state with globalGeneration -1 and empty meta data is returned.
57-
* @throws IOException if some IOException when loading files occurs or there is no metadata referenced by manifest file.
58-
*/
59-
@UpdateForV9(owner = UpdateForV9.Owner.DISTRIBUTED_COORDINATION)
60-
public Tuple<Manifest, Metadata> loadFullState() throws IOException {
61-
final Manifest manifest = Manifest.FORMAT.loadLatestState(logger, namedXContentRegistry, nodeEnv.nodeDataPaths());
62-
if (manifest == null) {
63-
return loadFullStateBWC();
64-
}
65-
66-
final Metadata.Builder metadataBuilder;
67-
if (manifest.isGlobalGenerationMissing()) {
68-
metadataBuilder = Metadata.builder();
69-
} else {
70-
final Metadata globalMetadata = Metadata.FORMAT.loadGeneration(
71-
logger,
72-
namedXContentRegistry,
73-
manifest.globalGeneration(),
74-
nodeEnv.nodeDataPaths()
75-
);
76-
if (globalMetadata != null) {
77-
metadataBuilder = Metadata.builder(globalMetadata);
78-
} else {
79-
throw new IOException("failed to find global metadata [generation: " + manifest.globalGeneration() + "]");
80-
}
81-
}
82-
83-
for (Map.Entry<Index, Long> entry : manifest.indexGenerations().entrySet()) {
84-
final Index index = entry.getKey();
85-
final long generation = entry.getValue();
86-
final String indexFolderName = index.getUUID();
87-
final IndexMetadata indexMetadata = IndexMetadata.FORMAT.loadGeneration(
88-
logger,
89-
namedXContentRegistry,
90-
generation,
91-
nodeEnv.resolveIndexFolder(indexFolderName)
92-
);
93-
if (indexMetadata != null) {
94-
metadataBuilder.put(indexMetadata, false);
95-
} else {
96-
throw new IOException(
97-
"failed to find metadata for existing index "
98-
+ index.getName()
99-
+ " [location: "
100-
+ indexFolderName
101-
+ ", generation: "
102-
+ generation
103-
+ "]"
104-
);
105-
}
106-
}
107-
108-
return new Tuple<>(manifest, metadataBuilder.build());
109-
}
110-
111-
/**
112-
* "Manifest-less" BWC version of loading metadata from disk. See also {@link #loadFullState()}
113-
*/
114-
private Tuple<Manifest, Metadata> loadFullStateBWC() throws IOException {
115-
Map<Index, Long> indices = new HashMap<>();
116-
Metadata.Builder metadataBuilder;
117-
118-
Tuple<Metadata, Long> metadataAndGeneration = Metadata.FORMAT.loadLatestStateWithGeneration(
119-
logger,
120-
namedXContentRegistry,
121-
nodeEnv.nodeDataPaths()
122-
);
123-
Metadata globalMetadata = metadataAndGeneration.v1();
124-
long globalStateGeneration = metadataAndGeneration.v2();
125-
126-
final IndexGraveyard indexGraveyard;
127-
if (globalMetadata != null) {
128-
metadataBuilder = Metadata.builder(globalMetadata);
129-
indexGraveyard = globalMetadata.custom(IndexGraveyard.TYPE);
130-
} else {
131-
metadataBuilder = Metadata.builder();
132-
indexGraveyard = IndexGraveyard.builder().build();
133-
}
134-
135-
for (String indexFolderName : nodeEnv.availableIndexFolders()) {
136-
Tuple<IndexMetadata, Long> indexMetadataAndGeneration = IndexMetadata.FORMAT.loadLatestStateWithGeneration(
137-
logger,
138-
namedXContentRegistry,
139-
nodeEnv.resolveIndexFolder(indexFolderName)
140-
);
141-
IndexMetadata indexMetadata = indexMetadataAndGeneration.v1();
142-
long generation = indexMetadataAndGeneration.v2();
143-
if (indexMetadata != null) {
144-
if (indexGraveyard.containsIndex(indexMetadata.getIndex())) {
145-
logger.debug("[{}] found metadata for deleted index [{}]", indexFolderName, indexMetadata.getIndex());
146-
// this index folder is cleared up when state is recovered
147-
} else {
148-
indices.put(indexMetadata.getIndex(), generation);
149-
metadataBuilder.put(indexMetadata, false);
150-
}
151-
} else {
152-
logger.debug("[{}] failed to find metadata for existing index location", indexFolderName);
153-
}
154-
}
155-
156-
Manifest manifest = Manifest.unknownCurrentTermAndVersion(globalStateGeneration, indices);
157-
return new Tuple<>(manifest, metadataBuilder.build());
158-
}
159-
16043
/**
16144
* Loads the index state for the provided index name, returning null if doesn't exists.
16245
*/
@@ -193,7 +76,7 @@ List<IndexMetadata> loadIndicesStates(Predicate<String> excludeIndexPathIdsPredi
19376
}
19477

19578
/**
196-
* Loads the global state, *without* index state, see {@link #loadFullState()} for that.
79+
* Loads the global state, *without* index state
19780
*/
19881
Metadata loadGlobalState() throws IOException {
19982
return Metadata.FORMAT.loadLatestState(logger, namedXContentRegistry, nodeEnv.nodeDataPaths());

server/src/main/java/org/elasticsearch/node/Node.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ public Node start() throws NodeValidationException {
325325
// TODO: Do not expect that the legacy metadata file is always present https://github.com/elastic/elasticsearch/issues/95211
326326
if (Assertions.ENABLED && DiscoveryNode.isStateless(settings()) == false) {
327327
try {
328-
assert injector.getInstance(MetaStateService.class).loadFullState().v1().isEmpty();
329328
final NodeMetadata nodeMetadata = NodeMetadata.FORMAT.loadLatestState(
330329
logger,
331330
NamedXContentRegistry.EMPTY,

0 commit comments

Comments
 (0)