From 9fa60f7367b2817ad340264b67f5aae8871072a4 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Mon, 25 May 2020 11:26:03 +0200 Subject: [PATCH] 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. --- .../UnsafeBootstrapAndDetachCommandIT.java | 4 ++++ .../indices/recovery/DanglingIndicesIT.java | 4 ++++ .../snapshots/SharedClusterSnapshotRestoreIT.java | 2 ++ .../indices/shrink/TransportResizeAction.java | 6 ++++-- .../coordination/UnsafeBootstrapMasterCommand.java | 14 +++++++++++--- .../cluster/metadata/IndexMetadata.java | 1 + .../common/settings/IndexScopedSettings.java | 1 + .../gateway/LocalAllocateDangledIndices.java | 5 +++++ .../org/elasticsearch/index/IndexSettings.java | 5 +++++ .../elasticsearch/snapshots/RestoreService.java | 8 +++++--- .../ccr/action/TransportResumeFollowAction.java | 1 + 11 files changed, 43 insertions(+), 8 deletions(-) diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/UnsafeBootstrapAndDetachCommandIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/UnsafeBootstrapAndDetachCommandIT.java index 8d270d7dbdf..0713b00d24a 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/UnsafeBootstrapAndDetachCommandIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/UnsafeBootstrapAndDetachCommandIT.java @@ -23,6 +23,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.cli.MockTerminal; import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.discovery.DiscoverySettings; @@ -47,6 +48,7 @@ import static org.elasticsearch.indices.recovery.RecoverySettings.INDICES_RECOVE import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, autoManageMasterNodes = false) public class UnsafeBootstrapAndDetachCommandIT extends ESIntegTestCase { @@ -293,6 +295,8 @@ public class UnsafeBootstrapAndDetachCommandIT extends ESIntegTestCase { logger.info("--> ensure index test is green"); ensureGreen("test"); + IndexMetadata indexMetadata = clusterService().state().metadata().index("test"); + assertThat(indexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), notNullValue()); logger.info("--> detach-cluster on 2nd and 3rd master-eligible nodes"); Environment environmentMaster2 = TestEnvironment.newEnvironment( diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/DanglingIndicesIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/DanglingIndicesIT.java index b99b419e0c8..74af1162db0 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/DanglingIndicesIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/DanglingIndicesIT.java @@ -19,6 +19,7 @@ package org.elasticsearch.indices.recovery; +import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.indices.IndicesService; import org.elasticsearch.test.ESIntegTestCase; @@ -31,6 +32,7 @@ import static org.elasticsearch.cluster.metadata.IndexGraveyard.SETTING_MAX_TOMB import static org.elasticsearch.gateway.DanglingIndicesState.AUTO_IMPORT_DANGLING_INDICES_SETTING; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; @ClusterScope(numDataNodes = 0, scope = ESIntegTestCase.Scope.TEST) public class DanglingIndicesIT extends ESIntegTestCase { @@ -89,6 +91,8 @@ public class DanglingIndicesIT extends ESIntegTestCase { equalTo("42s")); } ensureGreen(INDEX_NAME); + final IndexMetadata indexMetadata = clusterService().state().metadata().index(INDEX_NAME); + assertThat(indexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), notNullValue()); } /** diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index cbf446a8322..5c977436997 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -3597,6 +3597,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas final IndexMetadata indexMetadata = client().admin().cluster().prepareState().clear().setIndices(indexName) .setMetadata(true).get().getState().metadata().index(indexName); + assertThat(indexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), nullValue()); final int numPrimaries = getNumShards(indexName).numPrimaries; final Map primaryTerms = IntStream.range(0, numPrimaries) .boxed().collect(Collectors.toMap(shardId -> shardId, indexMetadata::primaryTerm)); @@ -3619,6 +3620,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas for (int shardId = 0; shardId < numPrimaries; shardId++) { assertThat(restoredIndexMetadata.primaryTerm(shardId), greaterThan(primaryTerms.get(shardId))); } + assertThat(restoredIndexMetadata.getSettings().get(IndexMetadata.SETTING_HISTORY_UUID), notNullValue()); } public void testSnapshotDifferentIndicesBySameName() { diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/TransportResizeAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/TransportResizeAction.java index f30777c999d..bc864545295 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/TransportResizeAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/shrink/TransportResizeAction.java @@ -121,8 +121,10 @@ public class TransportResizeAction extends TransportMasterNodeAction idx : metadata.indices().values()) { + IndexMetadata indexMetadata = idx.value; + newMetadata.put(IndexMetadata.builder(indexMetadata).settings( + Settings.builder().put(indexMetadata.getSettings()) + .put(IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID()))); + } final ClusterState newClusterState = ClusterState.builder(oldClusterState) .metadata(newMetadata).build(); diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java index 4049a2f0034..defdb3dbbc7 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java @@ -227,6 +227,7 @@ public class IndexMetadata implements Diffable, ToXContentFragmen Setting.intSetting("index.priority", 1, 0, Property.Dynamic, Property.IndexScope); public static final String SETTING_CREATION_DATE_STRING = "index.creation_date_string"; public static final String SETTING_INDEX_UUID = "index.uuid"; + public static final String SETTING_HISTORY_UUID = "index.history.uuid"; public static final String SETTING_DATA_PATH = "index.data_path"; public static final Setting INDEX_DATA_PATH_SETTING = new Setting<>(SETTING_DATA_PATH, "", Function.identity(), Property.IndexScope); diff --git a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index 6f620f5cc2f..d6442f6c835 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -214,6 +214,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings { switch (key) { case IndexMetadata.SETTING_CREATION_DATE: case IndexMetadata.SETTING_INDEX_UUID: + case IndexMetadata.SETTING_HISTORY_UUID: case IndexMetadata.SETTING_VERSION_UPGRADED: case IndexMetadata.SETTING_INDEX_PROVIDED_NAME: case MergePolicyConfig.INDEX_MERGE_ENABLED: diff --git a/server/src/main/java/org/elasticsearch/gateway/LocalAllocateDangledIndices.java b/server/src/main/java/org/elasticsearch/gateway/LocalAllocateDangledIndices.java index deaaddb288b..06833b82fd5 100644 --- a/server/src/main/java/org/elasticsearch/gateway/LocalAllocateDangledIndices.java +++ b/server/src/main/java/org/elasticsearch/gateway/LocalAllocateDangledIndices.java @@ -35,9 +35,11 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.routing.RoutingTable; import org.elasticsearch.cluster.routing.allocation.AllocationService; import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.discovery.MasterNotDiscoveredException; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; @@ -142,6 +144,9 @@ public class LocalAllocateDangledIndices { // with the current version and upgrade it if needed. upgradedIndexMetadata = metadataIndexUpgradeService.upgradeIndexMetadata(indexMetadata, minIndexCompatibilityVersion); + upgradedIndexMetadata = IndexMetadata.builder(upgradedIndexMetadata).settings( + Settings.builder().put(upgradedIndexMetadata.getSettings()).put( + IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID())).build(); } catch (Exception ex) { // upgrade failed - adding index as closed logger.warn(() -> new ParameterizedMessage("found dangled index [{}] on node [{}]. This index cannot be " + diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java index ca10d36e32b..1134ace433f 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -708,6 +708,11 @@ public final class IndexSettings { if (newUUID.equals(getUUID()) == false) { throw new IllegalArgumentException("uuid mismatch on settings update expected: " + getUUID() + " but was: " + newUUID); } + final String newRestoreUUID = newSettings.get(IndexMetadata.SETTING_HISTORY_UUID, IndexMetadata.INDEX_UUID_NA_VALUE); + final String restoreUUID = this.settings.get(IndexMetadata.SETTING_HISTORY_UUID, IndexMetadata.INDEX_UUID_NA_VALUE); + if (newRestoreUUID.equals(restoreUUID) == false) { + throw new IllegalArgumentException("uuid mismatch on settings update expected: " + restoreUUID + " but was: " + newRestoreUUID); + } this.indexMetadata = indexMetadata; final Settings newIndexSettings = Settings.builder().put(nodeSettings).put(newSettings).build(); if (same(this.settings, newIndexSettings)) { diff --git a/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java b/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java index 831f2782c02..e14f1120a08 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/RestoreService.java @@ -91,6 +91,7 @@ import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_CREATION_ import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_INDEX_UUID; import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_REPLICAS; import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_SHARDS; +import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_HISTORY_UUID; import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_VERSION_CREATED; import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_VERSION_UPGRADED; import static org.elasticsearch.common.util.set.Sets.newHashSet; @@ -125,7 +126,8 @@ public class RestoreService implements ClusterStateApplier { SETTING_VERSION_CREATED, SETTING_INDEX_UUID, SETTING_CREATION_DATE, - IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey())); + IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), + SETTING_HISTORY_UUID)); // It's OK to change some settings, but we shouldn't allow simply removing them private static final Set UNREMOVABLE_SETTINGS; @@ -342,8 +344,8 @@ public class RestoreService implements ClusterStateApplier { } indexMdBuilder.settings(Settings.builder() .put(snapshotIndexMetadata.getSettings()) - .put(IndexMetadata.SETTING_INDEX_UUID, - currentIndexMetadata.getIndexUUID())); + .put(IndexMetadata.SETTING_INDEX_UUID, currentIndexMetadata.getIndexUUID()) + .put(IndexMetadata.SETTING_HISTORY_UUID, UUIDs.randomBase64UUID())); IndexMetadata updatedIndexMetadata = indexMdBuilder.index(renamedIndexName).build(); rtBuilder.addAsRestore(updatedIndexMetadata, recoverySource); blocks.updateBlocks(updatedIndexMetadata); diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java index e3b792cabf5..13aabfd85cf 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java @@ -456,6 +456,7 @@ public class TransportResumeFollowAction extends TransportMasterNodeAction