Skip to content

Commit ce91ba7

Browse files
Dangling indices strip aliases (#47581)
Importing dangling indices with aliases risks breaking functionalities using those aliases. For instance, writing to an alias may break if there is no is_write_index indication on the existing alias and the dangling index import adds a second index to the alias. Or an application could have an assumption about the alias only ever pointing to one index and suddenly seeing the alias also linked to an old index could break it. With this change we strip aliases of the index meta data found before importing a dangling index.
1 parent bb5f750 commit ce91ba7

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ Map<Index, IndexMetaData> findNewDanglingIndices(final MetaData metaData) {
144144
} else {
145145
logger.info("[{}] dangling index exists on local file system, but not in cluster metadata, " +
146146
"auto import to cluster state", indexMetaData.getIndex());
147-
newIndices.put(indexMetaData.getIndex(), indexMetaData);
147+
newIndices.put(indexMetaData.getIndex(), stripAliases(indexMetaData));
148148
}
149149
}
150150
return newIndices;
@@ -154,6 +154,20 @@ Map<Index, IndexMetaData> findNewDanglingIndices(final MetaData metaData) {
154154
}
155155
}
156156

157+
/**
158+
* Dangling importing indices with aliases is dangerous, it could for instance result in inability to write to an existing alias if it
159+
* previously had only one index with any is_write_index indication.
160+
*/
161+
private IndexMetaData stripAliases(IndexMetaData indexMetaData) {
162+
if (indexMetaData.getAliases().isEmpty()) {
163+
return indexMetaData;
164+
} else {
165+
logger.info("[{}] stripping aliases: {} from index before importing",
166+
indexMetaData.getIndex(), indexMetaData.getAliases().keys());
167+
return IndexMetaData.builder(indexMetaData).removeAllAliases().build();
168+
}
169+
}
170+
157171
/**
158172
* Allocates the provided list of the dangled indices by sending them to the master node
159173
* for allocation.

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.elasticsearch.gateway;
2020

2121
import org.elasticsearch.Version;
22+
import org.elasticsearch.cluster.metadata.AliasMetaData;
2223
import org.elasticsearch.cluster.metadata.IndexGraveyard;
2324
import org.elasticsearch.cluster.metadata.IndexMetaData;
2425
import org.elasticsearch.cluster.metadata.MetaData;
@@ -158,6 +159,28 @@ public void testDanglingIndicesNotImportedWhenTombstonePresent() throws Exceptio
158159
}
159160
}
160161

162+
public void testDanglingIndicesStripAliases() throws Exception {
163+
try (NodeEnvironment env = newNodeEnvironment()) {
164+
MetaStateService metaStateService = new MetaStateService(env, xContentRegistry());
165+
DanglingIndicesState danglingState = createDanglingIndicesState(env, metaStateService);
166+
167+
final Settings.Builder settings = Settings.builder().put(indexSettings).put(IndexMetaData.SETTING_INDEX_UUID, "test1UUID");
168+
IndexMetaData dangledIndex = IndexMetaData.builder("test1")
169+
.settings(settings)
170+
.putAlias(AliasMetaData.newAliasMetaDataBuilder("test_aliasd").build())
171+
.build();
172+
metaStateService.writeIndex("test_write", dangledIndex);
173+
assertThat(dangledIndex.getAliases().size(), equalTo(1));
174+
175+
final MetaData metaData = MetaData.builder().build();
176+
Map<Index, IndexMetaData> newDanglingIndices = danglingState.findNewDanglingIndices(metaData);
177+
assertThat(newDanglingIndices.size(), equalTo(1));
178+
Map.Entry<Index, IndexMetaData> entry = newDanglingIndices.entrySet().iterator().next();
179+
assertThat(entry.getKey().getName(), equalTo("test1"));
180+
assertThat(entry.getValue().getAliases().size(), equalTo(0));
181+
}
182+
}
183+
161184
private DanglingIndicesState createDanglingIndicesState(NodeEnvironment env, MetaStateService metaStateService) {
162185
return new DanglingIndicesState(env, metaStateService, null, mock(ClusterService.class));
163186
}

0 commit comments

Comments
 (0)