Skip to content

Commit 560b3e3

Browse files
authored
Prohibit changes to index mode, source, and sort settings during restore (#115811)
The index.mode, source.mode, and index.sort.* settings cannot be modified during restore, as this may lead to data corruption or issues retrieving _source. This change enforces a restriction on modifying these settings during restore. While a fine-grained check could permit equivalent settings, it seems simpler and safer to reject restore requests if any of these settings are specified.
1 parent 0e1d2d9 commit 560b3e3

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

docs/changelog/115811.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 115811
2+
summary: "Prohibit changes to index mode, source, and sort settings during restore"
3+
area: Logs
4+
type: bug
5+
issues: []

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.common.settings.Settings;
2424
import org.elasticsearch.common.unit.ByteSizeUnit;
2525
import org.elasticsearch.core.TimeValue;
26+
import org.elasticsearch.index.IndexMode;
2627
import org.elasticsearch.index.IndexVersion;
2728
import org.elasticsearch.index.IndexVersions;
2829
import org.elasticsearch.indices.InvalidIndexNameException;
@@ -761,6 +762,68 @@ public void testChangeSettingsOnRestore() throws Exception {
761762
assertHitCount(client.prepareSearch("test-idx").setSize(0).setQuery(matchQuery("field1", "bar")), numdocs);
762763
}
763764

765+
public void testRestoreChangeIndexMode() {
766+
Client client = client();
767+
createRepository("test-repo", "fs");
768+
String indexName = "test-idx";
769+
assertAcked(client.admin().indices().prepareCreate(indexName).setSettings(Settings.builder().put(indexSettings())));
770+
createSnapshot("test-repo", "test-snap", Collections.singletonList(indexName));
771+
cluster().wipeIndices(indexName);
772+
for (IndexMode mode : IndexMode.values()) {
773+
var error = expectThrows(SnapshotRestoreException.class, () -> {
774+
client.admin()
775+
.cluster()
776+
.prepareRestoreSnapshot(TEST_REQUEST_TIMEOUT, "test-repo", "test-snap")
777+
.setIndexSettings(Settings.builder().put("index.mode", mode.name()))
778+
.setWaitForCompletion(true)
779+
.get();
780+
});
781+
assertThat(error.getMessage(), containsString("cannot modify setting [index.mode] on restore"));
782+
}
783+
}
784+
785+
public void testRestoreChangeSyntheticSource() {
786+
Client client = client();
787+
createRepository("test-repo", "fs");
788+
String indexName = "test-idx";
789+
assertAcked(client.admin().indices().prepareCreate(indexName).setSettings(Settings.builder().put(indexSettings())));
790+
createSnapshot("test-repo", "test-snap", Collections.singletonList(indexName));
791+
cluster().wipeIndices(indexName);
792+
var error = expectThrows(SnapshotRestoreException.class, () -> {
793+
client.admin()
794+
.cluster()
795+
.prepareRestoreSnapshot(TEST_REQUEST_TIMEOUT, "test-repo", "test-snap")
796+
.setIndexSettings(Settings.builder().put("index.mapping.source.mode", "synthetic"))
797+
.setWaitForCompletion(true)
798+
.get();
799+
});
800+
assertThat(error.getMessage(), containsString("cannot modify setting [index.mapping.source.mode] on restore"));
801+
}
802+
803+
public void testRestoreChangeIndexSorts() {
804+
Client client = client();
805+
createRepository("test-repo", "fs");
806+
String indexName = "test-idx";
807+
assertAcked(
808+
client.admin()
809+
.indices()
810+
.prepareCreate(indexName)
811+
.setMapping("host.name", "type=keyword", "@timestamp", "type=date")
812+
.setSettings(Settings.builder().put(indexSettings()).putList("index.sort.field", List.of("@timestamp", "host.name")))
813+
);
814+
createSnapshot("test-repo", "test-snap", Collections.singletonList(indexName));
815+
cluster().wipeIndices(indexName);
816+
var error = expectThrows(SnapshotRestoreException.class, () -> {
817+
client.admin()
818+
.cluster()
819+
.prepareRestoreSnapshot(TEST_REQUEST_TIMEOUT, "test-repo", "test-snap")
820+
.setIndexSettings(Settings.builder().putList("index.sort.field", List.of("host.name")))
821+
.setWaitForCompletion(true)
822+
.get();
823+
});
824+
assertThat(error.getMessage(), containsString("cannot modify setting [index.sort.field] on restore"));
825+
}
826+
764827
public void testRecreateBlocksOnRestore() throws Exception {
765828
Client client = client();
766829

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@
6767
import org.elasticsearch.core.Tuple;
6868
import org.elasticsearch.index.Index;
6969
import org.elasticsearch.index.IndexSettings;
70+
import org.elasticsearch.index.IndexSortConfig;
7071
import org.elasticsearch.index.IndexVersion;
7172
import org.elasticsearch.index.mapper.MapperService;
7273
import org.elasticsearch.index.mapper.Mapping;
74+
import org.elasticsearch.index.mapper.SourceFieldMapper;
7375
import org.elasticsearch.index.shard.IndexLongFieldRange;
7476
import org.elasticsearch.index.shard.IndexShard;
7577
import org.elasticsearch.index.shard.ShardId;
@@ -155,7 +157,13 @@ public final class RestoreService implements ClusterStateApplier {
155157
SETTING_VERSION_CREATED,
156158
SETTING_INDEX_UUID,
157159
SETTING_CREATION_DATE,
158-
SETTING_HISTORY_UUID
160+
SETTING_HISTORY_UUID,
161+
IndexSettings.MODE.getKey(),
162+
SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.getKey(),
163+
IndexSortConfig.INDEX_SORT_FIELD_SETTING.getKey(),
164+
IndexSortConfig.INDEX_SORT_ORDER_SETTING.getKey(),
165+
IndexSortConfig.INDEX_SORT_MODE_SETTING.getKey(),
166+
IndexSortConfig.INDEX_SORT_MISSING_SETTING.getKey()
159167
);
160168

161169
// It's OK to change some settings, but we shouldn't allow simply removing them

0 commit comments

Comments
 (0)