From 867d88795be44f6557dab85b731c002c2856f7e5 Mon Sep 17 00:00:00 2001 From: Boaz Leskes Date: Mon, 7 Jul 2014 21:11:59 +0200 Subject: [PATCH] [Recovery] only send mapping updates to master if needed The change added in #6762 helps making sure the pending mapping updates are processed on all nodes to prevent moving shards to nodes which are not yet fully aware of the new mapping. However it introduced a racing condition delete_mapping operations, potentially causing a type to be added after it's deletion. This commit solves this by only sending a mapping update if the mapping source has actually changed. Closes #6772 --- .../indices/recovery/RecoverySource.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/elasticsearch/indices/recovery/RecoverySource.java b/src/main/java/org/elasticsearch/indices/recovery/RecoverySource.java index d6c02d46b2b..2515af8da62 100644 --- a/src/main/java/org/elasticsearch/indices/recovery/RecoverySource.java +++ b/src/main/java/org/elasticsearch/indices/recovery/RecoverySource.java @@ -27,10 +27,13 @@ import org.apache.lucene.util.IOUtils; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.action.index.MappingUpdatedAction; +import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.cluster.routing.RoutingNode; import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.common.StopWatch; import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.compress.CompressorFactory; import org.elasticsearch.common.inject.Inject; @@ -280,6 +283,11 @@ public class RecoverySource extends AbstractComponent { } private void updateMappingOnMaster() { + IndexMetaData indexMetaData = clusterService.state().metaData().getIndices().get(indexService.index().getName()); + ImmutableOpenMap metaDataMappings = null; + if (indexMetaData != null) { + metaDataMappings = indexMetaData.getMappings(); + } List documentMappersToUpdate = Lists.newArrayList(); for (DocumentMapper documentMapper : indexService.mapperService()) { // default mapping should not be sent back, it can only be updated by put mapping API, and its @@ -287,7 +295,12 @@ public class RecoverySource extends AbstractComponent { if (documentMapper.type().equals(MapperService.DEFAULT_MAPPING)) { continue; } - documentMappersToUpdate.add(documentMapper); + + MappingMetaData mappingMetaData = metaDataMappings == null ? null : metaDataMappings.get(documentMapper.type()); + if (mappingMetaData == null || !documentMapper.refreshSource().equals(mappingMetaData.source())) { + // not on master yet in the right form + documentMappersToUpdate.add(documentMapper); + } } if (documentMappersToUpdate.isEmpty()) { return;