Skip to content

Commit ee56a36

Browse files
Add History UUID Index Setting (#56930)
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 b82a16e commit ee56a36

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.env.Environment;
@@ -46,6 +47,7 @@
4647
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
4748
import static org.hamcrest.Matchers.containsString;
4849
import static org.hamcrest.Matchers.equalTo;
50+
import static org.hamcrest.Matchers.notNullValue;
4951

5052
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, autoManageMasterNodes = false)
5153
public class UnsafeBootstrapAndDetachCommandIT extends ESIntegTestCase {
@@ -292,6 +294,8 @@ public void test3MasterNodes2Failed() throws Exception {
292294

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

296300
logger.info("--> detach-cluster on 2nd and 3rd master-eligible nodes");
297301
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
@@ -3689,6 +3689,7 @@ public void testRestoreIncreasesPrimaryTerms() {
36893689

36903690
final IndexMetadata indexMetadata = client().admin().cluster().prepareState().clear().setIndices(indexName)
36913691
.setMetadata(true).get().getState().metadata().index(indexName);
3692+
assertThat(indexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), nullValue());
36923693
final int numPrimaries = getNumShards(indexName).numPrimaries;
36933694
final Map<Integer, Long> primaryTerms = IntStream.range(0, numPrimaries)
36943695
.boxed().collect(Collectors.toMap(shardId -> shardId, indexMetadata::primaryTerm));
@@ -3711,6 +3712,7 @@ public void testRestoreIncreasesPrimaryTerms() {
37113712
for (int shardId = 0; shardId < numPrimaries; shardId++) {
37123713
assertThat(restoredIndexMetadata.primaryTerm(shardId), greaterThan(primaryTerms.get(shardId)));
37133714
}
3715+
assertThat(restoredIndexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), notNullValue());
37143716
}
37153717

37163718
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
@@ -127,8 +127,10 @@ static CreateIndexClusterStateUpdateRequest prepareCreateIndexRequest(final Resi
127127
if (metadata == null) {
128128
throw new IndexNotFoundException(sourceIndexName);
129129
}
130-
final Settings targetIndexSettings = Settings.builder().put(targetIndex.settings())
131-
.normalizePrefix(IndexMetadata.INDEX_SETTING_PREFIX).build();
130+
final Settings.Builder targetIndexSettingsBuilder = Settings.builder().put(targetIndex.settings())
131+
.normalizePrefix(IndexMetadata.INDEX_SETTING_PREFIX);
132+
targetIndexSettingsBuilder.remove(IndexMetadata.SETTING_HISTORY_UUID);
133+
final Settings targetIndexSettings = targetIndexSettingsBuilder.build();
132134
final int numShards;
133135
if (IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.exists(targetIndexSettings)) {
134136
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;
@@ -106,13 +109,18 @@ protected void processNodePaths(Terminal terminal, Path[] dataPaths, OptionSet o
106109
.put(metadata.persistentSettings())
107110
.put(UNSAFE_BOOTSTRAP.getKey(), true)
108111
.build();
109-
Metadata newMetadata = Metadata.builder(metadata)
112+
Metadata.Builder newMetadata = Metadata.builder(metadata)
110113
.clusterUUID(Metadata.UNKNOWN_CLUSTER_UUID)
111114
.generateClusterUuidIfNeeded()
112115
.clusterUUIDCommitted(true)
113116
.persistentSettings(persistentSettings)
114-
.coordinationMetadata(newCoordinationMetadata)
115-
.build();
117+
.coordinationMetadata(newCoordinationMetadata);
118+
for (ObjectCursor<IndexMetadata> idx : metadata.indices().values()) {
119+
IndexMetadata indexMetadata = idx.value;
120+
newMetadata.put(IndexMetadata.builder(indexMetadata).settings(
121+
Settings.builder().put(indexMetadata.getSettings())
122+
.put(IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID())));
123+
}
116124

117125
final ClusterState newClusterState = ClusterState.builder(oldClusterState)
118126
.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
@@ -209,6 +209,7 @@ public boolean isPrivateSetting(String key) {
209209
switch (key) {
210210
case IndexMetadata.SETTING_CREATION_DATE:
211211
case IndexMetadata.SETTING_INDEX_UUID:
212+
case IndexMetadata.SETTING_HISTORY_UUID:
212213
case IndexMetadata.SETTING_VERSION_UPGRADED:
213214
case IndexMetadata.SETTING_INDEX_PROVIDED_NAME:
214215
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
@@ -663,6 +663,11 @@ public synchronized boolean updateIndexMetadata(IndexMetadata indexMetadata) {
663663
if (newUUID.equals(getUUID()) == false) {
664664
throw new IllegalArgumentException("uuid mismatch on settings update expected: " + getUUID() + " but was: " + newUUID);
665665
}
666+
final String newRestoreUUID = newSettings.get(IndexMetadata.SETTING_HISTORY_UUID, IndexMetadata.INDEX_UUID_NA_VALUE);
667+
final String restoreUUID = this.settings.get(IndexMetadata.SETTING_HISTORY_UUID, IndexMetadata.INDEX_UUID_NA_VALUE);
668+
if (newRestoreUUID.equals(restoreUUID) == false) {
669+
throw new IllegalArgumentException("uuid mismatch on settings update expected: " + restoreUUID + " but was: " + newRestoreUUID);
670+
}
666671
this.indexMetadata = indexMetadata;
667672
final Settings newIndexSettings = Settings.builder().put(nodeSettings).put(newSettings).build();
668673
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;
@@ -334,8 +336,8 @@ public ClusterState execute(ClusterState currentState) {
334336
}
335337
indexMdBuilder.settings(Settings.builder()
336338
.put(snapshotIndexMetadata.getSettings())
337-
.put(IndexMetadata.SETTING_INDEX_UUID,
338-
currentIndexMetadata.getIndexUUID()));
339+
.put(IndexMetadata.SETTING_INDEX_UUID, currentIndexMetadata.getIndexUUID())
340+
.put(IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID()));
339341
IndexMetadata updatedIndexMetadata = indexMdBuilder.index(renamedIndexName).build();
340342
rtBuilder.addAsRestore(updatedIndexMetadata, recoverySource);
341343
blocks.updateBlocks(updatedIndexMetadata);

0 commit comments

Comments
 (0)