Skip to content

Commit 37b286d

Browse files
authored
Prohibit changes to index mode, source, and sort settings during restore (#115811) (#115973)
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 6baa7c3 commit 37b286d

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
@@ -65,9 +65,11 @@
6565
import org.elasticsearch.core.Tuple;
6666
import org.elasticsearch.index.Index;
6767
import org.elasticsearch.index.IndexSettings;
68+
import org.elasticsearch.index.IndexSortConfig;
6869
import org.elasticsearch.index.IndexVersion;
6970
import org.elasticsearch.index.mapper.MapperService;
7071
import org.elasticsearch.index.mapper.Mapping;
72+
import org.elasticsearch.index.mapper.SourceFieldMapper;
7173
import org.elasticsearch.index.shard.IndexLongFieldRange;
7274
import org.elasticsearch.index.shard.IndexShard;
7375
import org.elasticsearch.index.shard.ShardId;
@@ -153,7 +155,13 @@ public final class RestoreService implements ClusterStateApplier {
153155
SETTING_VERSION_CREATED,
154156
SETTING_INDEX_UUID,
155157
SETTING_CREATION_DATE,
156-
SETTING_HISTORY_UUID
158+
SETTING_HISTORY_UUID,
159+
IndexSettings.MODE.getKey(),
160+
SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.getKey(),
161+
IndexSortConfig.INDEX_SORT_FIELD_SETTING.getKey(),
162+
IndexSortConfig.INDEX_SORT_ORDER_SETTING.getKey(),
163+
IndexSortConfig.INDEX_SORT_MODE_SETTING.getKey(),
164+
IndexSortConfig.INDEX_SORT_MISSING_SETTING.getKey()
157165
);
158166

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

0 commit comments

Comments
 (0)