Skip to content

Commit 9fa60f7

Browse files
Add History UUID Index Setting (#56930) (#57104)
Pre-requesite for #50278 to be able to uniquely identify index metadata by its version fields and UUIDs when restoring into closed indices.
1 parent a4eb3ed commit 9fa60f7

File tree

11 files changed

+43
-8
lines changed

11 files changed

+43
-8
lines changed

server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/UnsafeBootstrapAndDetachCommandIT.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
2424
import org.elasticsearch.cli.MockTerminal;
2525
import org.elasticsearch.cluster.ClusterState;
26+
import org.elasticsearch.cluster.metadata.IndexMetadata;
2627
import org.elasticsearch.cluster.metadata.Metadata;
2728
import org.elasticsearch.common.settings.Settings;
2829
import org.elasticsearch.discovery.DiscoverySettings;
@@ -47,6 +48,7 @@
4748
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
4849
import static org.hamcrest.Matchers.containsString;
4950
import static org.hamcrest.Matchers.equalTo;
51+
import static org.hamcrest.Matchers.notNullValue;
5052

5153
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, autoManageMasterNodes = false)
5254
public class UnsafeBootstrapAndDetachCommandIT extends ESIntegTestCase {
@@ -293,6 +295,8 @@ public void test3MasterNodes2Failed() throws Exception {
293295

294296
logger.info("--> ensure index test is green");
295297
ensureGreen("test");
298+
IndexMetadata indexMetadata = clusterService().state().metadata().index("test");
299+
assertThat(indexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), notNullValue());
296300

297301
logger.info("--> detach-cluster on 2nd and 3rd master-eligible nodes");
298302
Environment environmentMaster2 = TestEnvironment.newEnvironment(

server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/DanglingIndicesIT.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.elasticsearch.indices.recovery;
2121

22+
import org.elasticsearch.cluster.metadata.IndexMetadata;
2223
import org.elasticsearch.common.settings.Settings;
2324
import org.elasticsearch.indices.IndicesService;
2425
import org.elasticsearch.test.ESIntegTestCase;
@@ -31,6 +32,7 @@
3132
import static org.elasticsearch.gateway.DanglingIndicesState.AUTO_IMPORT_DANGLING_INDICES_SETTING;
3233
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
3334
import static org.hamcrest.Matchers.equalTo;
35+
import static org.hamcrest.Matchers.notNullValue;
3436

3537
@ClusterScope(numDataNodes = 0, scope = ESIntegTestCase.Scope.TEST)
3638
public class DanglingIndicesIT extends ESIntegTestCase {
@@ -89,6 +91,8 @@ public Settings onNodeStopped(String nodeName) throws Exception {
8991
equalTo("42s"));
9092
}
9193
ensureGreen(INDEX_NAME);
94+
final IndexMetadata indexMetadata = clusterService().state().metadata().index(INDEX_NAME);
95+
assertThat(indexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), notNullValue());
9296
}
9397

9498
/**

server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3597,6 +3597,7 @@ public void testRestoreIncreasesPrimaryTerms() {
35973597

35983598
final IndexMetadata indexMetadata = client().admin().cluster().prepareState().clear().setIndices(indexName)
35993599
.setMetadata(true).get().getState().metadata().index(indexName);
3600+
assertThat(indexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), nullValue());
36003601
final int numPrimaries = getNumShards(indexName).numPrimaries;
36013602
final Map<Integer, Long> primaryTerms = IntStream.range(0, numPrimaries)
36023603
.boxed().collect(Collectors.toMap(shardId -> shardId, indexMetadata::primaryTerm));
@@ -3619,6 +3620,7 @@ public void testRestoreIncreasesPrimaryTerms() {
36193620
for (int shardId = 0; shardId < numPrimaries; shardId++) {
36203621
assertThat(restoredIndexMetadata.primaryTerm(shardId), greaterThan(primaryTerms.get(shardId)));
36213622
}
3623+
assertThat(restoredIndexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), notNullValue());
36223624
}
36233625

36243626
public void testSnapshotDifferentIndicesBySameName() {

server/src/main/java/org/elasticsearch/action/admin/indices/shrink/TransportResizeAction.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,10 @@ static CreateIndexClusterStateUpdateRequest prepareCreateIndexRequest(final Resi
121121
if (metadata == null) {
122122
throw new IndexNotFoundException(sourceIndexName);
123123
}
124-
final Settings targetIndexSettings = Settings.builder().put(targetIndex.settings())
125-
.normalizePrefix(IndexMetadata.INDEX_SETTING_PREFIX).build();
124+
final Settings.Builder targetIndexSettingsBuilder = Settings.builder().put(targetIndex.settings())
125+
.normalizePrefix(IndexMetadata.INDEX_SETTING_PREFIX);
126+
targetIndexSettingsBuilder.remove(IndexMetadata.SETTING_HISTORY_UUID);
127+
final Settings targetIndexSettings = targetIndexSettingsBuilder.build();
126128
final int numShards;
127129
if (IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.exists(targetIndexSettings)) {
128130
numShards = IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.get(targetIndexSettings);

server/src/main/java/org/elasticsearch/cluster/coordination/UnsafeBootstrapMasterCommand.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
*/
1919
package org.elasticsearch.cluster.coordination;
2020

21+
import com.carrotsearch.hppc.cursors.ObjectCursor;
2122
import joptsimple.OptionSet;
2223
import org.elasticsearch.ElasticsearchException;
2324
import org.elasticsearch.cli.Terminal;
2425
import org.elasticsearch.cluster.ClusterState;
26+
import org.elasticsearch.cluster.metadata.IndexMetadata;
2527
import org.elasticsearch.cluster.metadata.Metadata;
2628
import org.elasticsearch.cluster.service.ClusterService;
29+
import org.elasticsearch.common.UUIDs;
2730
import org.elasticsearch.common.collect.Tuple;
2831
import org.elasticsearch.common.settings.Setting;
2932
import org.elasticsearch.common.settings.Settings;
@@ -107,13 +110,18 @@ protected void processNodePaths(Terminal terminal, Path[] dataPaths, int nodeLoc
107110
.put(metadata.persistentSettings())
108111
.put(UNSAFE_BOOTSTRAP.getKey(), true)
109112
.build();
110-
Metadata newMetadata = Metadata.builder(metadata)
113+
Metadata.Builder newMetadata = Metadata.builder(metadata)
111114
.clusterUUID(Metadata.UNKNOWN_CLUSTER_UUID)
112115
.generateClusterUuidIfNeeded()
113116
.clusterUUIDCommitted(true)
114117
.persistentSettings(persistentSettings)
115-
.coordinationMetadata(newCoordinationMetadata)
116-
.build();
118+
.coordinationMetadata(newCoordinationMetadata);
119+
for (ObjectCursor<IndexMetadata> idx : metadata.indices().values()) {
120+
IndexMetadata indexMetadata = idx.value;
121+
newMetadata.put(IndexMetadata.builder(indexMetadata).settings(
122+
Settings.builder().put(indexMetadata.getSettings())
123+
.put(IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID())));
124+
}
117125

118126
final ClusterState newClusterState = ClusterState.builder(oldClusterState)
119127
.metadata(newMetadata).build();

server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ public Iterator<Setting<?>> settings() {
227227
Setting.intSetting("index.priority", 1, 0, Property.Dynamic, Property.IndexScope);
228228
public static final String SETTING_CREATION_DATE_STRING = "index.creation_date_string";
229229
public static final String SETTING_INDEX_UUID = "index.uuid";
230+
public static final String SETTING_HISTORY_UUID = "index.history.uuid";
230231
public static final String SETTING_DATA_PATH = "index.data_path";
231232
public static final Setting<String> INDEX_DATA_PATH_SETTING =
232233
new Setting<>(SETTING_DATA_PATH, "", Function.identity(), Property.IndexScope);

server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ public boolean isPrivateSetting(String key) {
214214
switch (key) {
215215
case IndexMetadata.SETTING_CREATION_DATE:
216216
case IndexMetadata.SETTING_INDEX_UUID:
217+
case IndexMetadata.SETTING_HISTORY_UUID:
217218
case IndexMetadata.SETTING_VERSION_UPGRADED:
218219
case IndexMetadata.SETTING_INDEX_PROVIDED_NAME:
219220
case MergePolicyConfig.INDEX_MERGE_ENABLED:

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@
3535
import org.elasticsearch.cluster.routing.RoutingTable;
3636
import org.elasticsearch.cluster.routing.allocation.AllocationService;
3737
import org.elasticsearch.cluster.service.ClusterService;
38+
import org.elasticsearch.common.UUIDs;
3839
import org.elasticsearch.common.inject.Inject;
3940
import org.elasticsearch.common.io.stream.StreamInput;
4041
import org.elasticsearch.common.io.stream.StreamOutput;
42+
import org.elasticsearch.common.settings.Settings;
4143
import org.elasticsearch.discovery.MasterNotDiscoveredException;
4244
import org.elasticsearch.tasks.Task;
4345
import org.elasticsearch.threadpool.ThreadPool;
@@ -142,6 +144,9 @@ public ClusterState execute(ClusterState currentState) {
142144
// with the current version and upgrade it if needed.
143145
upgradedIndexMetadata = metadataIndexUpgradeService.upgradeIndexMetadata(indexMetadata,
144146
minIndexCompatibilityVersion);
147+
upgradedIndexMetadata = IndexMetadata.builder(upgradedIndexMetadata).settings(
148+
Settings.builder().put(upgradedIndexMetadata.getSettings()).put(
149+
IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID())).build();
145150
} catch (Exception ex) {
146151
// upgrade failed - adding index as closed
147152
logger.warn(() -> new ParameterizedMessage("found dangled index [{}] on node [{}]. This index cannot be " +

server/src/main/java/org/elasticsearch/index/IndexSettings.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,11 @@ public synchronized boolean updateIndexMetadata(IndexMetadata indexMetadata) {
708708
if (newUUID.equals(getUUID()) == false) {
709709
throw new IllegalArgumentException("uuid mismatch on settings update expected: " + getUUID() + " but was: " + newUUID);
710710
}
711+
final String newRestoreUUID = newSettings.get(IndexMetadata.SETTING_HISTORY_UUID, IndexMetadata.INDEX_UUID_NA_VALUE);
712+
final String restoreUUID = this.settings.get(IndexMetadata.SETTING_HISTORY_UUID, IndexMetadata.INDEX_UUID_NA_VALUE);
713+
if (newRestoreUUID.equals(restoreUUID) == false) {
714+
throw new IllegalArgumentException("uuid mismatch on settings update expected: " + restoreUUID + " but was: " + newRestoreUUID);
715+
}
711716
this.indexMetadata = indexMetadata;
712717
final Settings newIndexSettings = Settings.builder().put(nodeSettings).put(newSettings).build();
713718
if (same(this.settings, newIndexSettings)) {

server/src/main/java/org/elasticsearch/snapshots/RestoreService.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_INDEX_UUID;
9292
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_REPLICAS;
9393
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_SHARDS;
94+
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_HISTORY_UUID;
9495
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_VERSION_CREATED;
9596
import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_VERSION_UPGRADED;
9697
import static org.elasticsearch.common.util.set.Sets.newHashSet;
@@ -125,7 +126,8 @@ public class RestoreService implements ClusterStateApplier {
125126
SETTING_VERSION_CREATED,
126127
SETTING_INDEX_UUID,
127128
SETTING_CREATION_DATE,
128-
IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey()));
129+
IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(),
130+
SETTING_HISTORY_UUID));
129131

130132
// It's OK to change some settings, but we shouldn't allow simply removing them
131133
private static final Set<String> UNREMOVABLE_SETTINGS;
@@ -342,8 +344,8 @@ public ClusterState execute(ClusterState currentState) {
342344
}
343345
indexMdBuilder.settings(Settings.builder()
344346
.put(snapshotIndexMetadata.getSettings())
345-
.put(IndexMetadata.SETTING_INDEX_UUID,
346-
currentIndexMetadata.getIndexUUID()));
347+
.put(IndexMetadata.SETTING_INDEX_UUID, currentIndexMetadata.getIndexUUID())
348+
.put(IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID()));
347349
IndexMetadata updatedIndexMetadata = indexMdBuilder.index(renamedIndexName).build();
348350
rtBuilder.addAsRestore(updatedIndexMetadata, recoverySource);
349351
blocks.updateBlocks(updatedIndexMetadata);

0 commit comments

Comments
 (0)