Restore process should replace the mapping and settings if index already exists

Closes #5210
This commit is contained in:
Igor Motov 2014-02-20 15:25:45 -05:00
parent 4e6610a798
commit dab1f76e03
2 changed files with 53 additions and 1 deletions

View File

@ -191,7 +191,8 @@ public class RestoreService extends AbstractComponent implements ClusterStateLis
"] shard from snapshot with [" + snapshotIndexMetaData.getNumberOfShards() + "] shards"); "] shard from snapshot with [" + snapshotIndexMetaData.getNumberOfShards() + "] shards");
} }
// Index exists and it's closed - open it in metadata and start recovery // Index exists and it's closed - open it in metadata and start recovery
IndexMetaData.Builder indexMdBuilder = IndexMetaData.builder(currentIndexMetaData).state(IndexMetaData.State.OPEN); IndexMetaData.Builder indexMdBuilder = IndexMetaData.builder(snapshotIndexMetaData).state(IndexMetaData.State.OPEN);
indexMdBuilder.version(Math.max(snapshotIndexMetaData.version(), currentIndexMetaData.version() + 1));
IndexMetaData updatedIndexMetaData = indexMdBuilder.index(renamedIndex).build(); IndexMetaData updatedIndexMetaData = indexMdBuilder.index(renamedIndex).build();
rtBuilder.addAsRestore(updatedIndexMetaData, restoreSource); rtBuilder.addAsRestore(updatedIndexMetaData, restoreSource);
blocks.removeIndexBlock(index, INDEX_CLOSED_BLOCK); blocks.removeIndexBlock(index, INDEX_CLOSED_BLOCK);

View File

@ -29,12 +29,15 @@ import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRes
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.action.count.CountResponse; import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
@ -138,6 +141,54 @@ public class SharedClusterSnapshotRestoreTests extends AbstractSnapshotTests {
assertThat(clusterState.getMetaData().hasIndex("test-idx-2"), equalTo(false)); assertThat(clusterState.getMetaData().hasIndex("test-idx-2"), equalTo(false));
} }
@Test
public void restoreWithDifferentMappingsAndSettingsTest() throws Exception {
Client client = client();
logger.info("--> creating repository");
PutRepositoryResponse putRepositoryResponse = client.admin().cluster().preparePutRepository("test-repo")
.setType("fs").setSettings(ImmutableSettings.settingsBuilder()
.put("location", newTempDir(LifecycleScope.SUITE))
.put("compress", randomBoolean())
.put("chunk_size", randomIntBetween(100, 1000))
).get();
assertThat(putRepositoryResponse.isAcknowledged(), equalTo(true));
logger.info("--> create index with foo type");
assertAcked(prepareCreate("test-idx", 2, ImmutableSettings.builder().put("refresh_interval", 10)));
assertAcked(client().admin().indices().preparePutMapping("test-idx").setType("foo").setSource("baz", "type=string"));
ensureGreen();
logger.info("--> snapshot it");
CreateSnapshotResponse createSnapshotResponse = client.admin().cluster().prepareCreateSnapshot("test-repo", "test-snap").setWaitForCompletion(true).setIndices("test-idx").get();
assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), greaterThan(0));
assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(createSnapshotResponse.getSnapshotInfo().totalShards()));
logger.info("--> delete the index and recreate it with bar type");
wipeIndices("test-idx");
assertAcked(prepareCreate("test-idx", 2, ImmutableSettings.builder().put("refresh_interval", 5)));
assertAcked(client().admin().indices().preparePutMapping("test-idx").setType("bar").setSource("baz", "type=string"));
ensureGreen();
logger.info("--> close index");
client.admin().indices().prepareClose("test-idx").get();
logger.info("--> restore all indices from the snapshot");
RestoreSnapshotResponse restoreSnapshotResponse = client.admin().cluster().prepareRestoreSnapshot("test-repo", "test-snap").setWaitForCompletion(true).execute().actionGet();
assertThat(restoreSnapshotResponse.getRestoreInfo().totalShards(), greaterThan(0));
ensureGreen();
logger.info("--> assert that old mapping is restored");
ImmutableOpenMap<String, MappingMetaData> mappings = client().admin().cluster().prepareState().get().getState().getMetaData().getIndices().get("test-idx").getMappings();
assertThat(mappings.get("foo"), notNullValue());
assertThat(mappings.get("bar"), nullValue());
logger.info("--> assert that old settings are restored");
GetSettingsResponse getSettingsResponse = client.admin().indices().prepareGetSettings("test-idx").execute().actionGet();
assertThat(getSettingsResponse.getSetting("test-idx", "index.refresh_interval"), equalTo("10"));
}
@Test @Test
public void emptySnapshotTest() throws Exception { public void emptySnapshotTest() throws Exception {
Client client = client(); Client client = client();