Skip to content

Commit

Permalink
Shortcut mapping update if the incoming mapping version is the same a…
Browse files Browse the repository at this point in the history
…s the current mapping version (#59517) (#59772)

Currently, when we apply a cluster state change to a shard on a non-master node,
we check to see if the mappings need to be updated by comparing the decompressed
serialized mappings from the update against the serialized version of the shard's
existing mappings. However, we already have a much simpler way of checking this,
by comparing mapping versions on the index metadata of the old and new states.

This commit adds a shortcut to MapperService.updateMappings() that compares
these mapping versions, and ignores the merge if they are equal.
  • Loading branch information
romseygeek authored Jul 17, 2020
1 parent b29d368 commit 65f6fb8
Showing 1 changed file with 16 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ public static Map<String, Object> parseMapping(NamedXContentRegistry xContentReg
public boolean updateMapping(final IndexMetadata currentIndexMetadata, final IndexMetadata newIndexMetadata) throws IOException {
assert newIndexMetadata.getIndex().equals(index()) : "index mismatch: expected " + index()
+ " but was " + newIndexMetadata.getIndex();

if (currentIndexMetadata != null && currentIndexMetadata.getMappingVersion() == newIndexMetadata.getMappingVersion()) {
assertMappingVersion(currentIndexMetadata, newIndexMetadata, Collections.emptyMap());
return false;
}

// go over and add the relevant mappings (or update them)
Set<String> existingMappers = new HashSet<>();
if (mapper != null) {
Expand All @@ -230,7 +236,7 @@ public boolean updateMapping(final IndexMetadata currentIndexMetadata, final Ind
final Map<String, DocumentMapper> updatedEntries;
try {
// only update entries if needed
updatedEntries = internalMerge(newIndexMetadata, MergeReason.MAPPING_RECOVERY, true);
updatedEntries = internalMerge(newIndexMetadata, MergeReason.MAPPING_RECOVERY);
} catch (Exception e) {
logger.warn(() -> new ParameterizedMessage("[{}] failed to apply mappings", index()), e);
throw e;
Expand Down Expand Up @@ -278,7 +284,7 @@ public boolean updateMapping(final IndexMetadata currentIndexMetadata, final Ind
private void assertMappingVersion(
final IndexMetadata currentIndexMetadata,
final IndexMetadata newIndexMetadata,
final Map<String, DocumentMapper> updatedEntries) {
final Map<String, DocumentMapper> updatedEntries) throws IOException {
if (Assertions.ENABLED
&& currentIndexMetadata != null
&& currentIndexMetadata.getCreationVersion().onOrAfter(Version.V_6_5_0)) {
Expand All @@ -302,10 +308,14 @@ private void assertMappingVersion(
assert currentSource.equals(newSource) :
"expected current mapping [" + currentSource + "] for type [" + mapping.type() + "] "
+ "to be the same as new mapping [" + newSource + "]";
final CompressedXContent mapperSource = new CompressedXContent(Strings.toString(mapper));
assert currentSource.equals(mapperSource) :
"expected current mapping [" + currentSource + "] for type [" + mapping.type() + "] "
+ "to be the same as new mapping [" + mapperSource + "]";
}

} else {
// if the mapping version is changed, it should increase, there should be updates, and the mapping should be different
// the mapping version should increase, there should be updates, and the mapping should be different
final long currentMappingVersion = currentIndexMetadata.getMappingVersion();
final long newMappingVersion = newIndexMetadata.getMappingVersion();
assert currentMappingVersion < newMappingVersion :
Expand Down Expand Up @@ -352,27 +362,19 @@ public void merge(String type, Map<String, Object> mappings, MergeReason reason)
}

public void merge(IndexMetadata indexMetadata, MergeReason reason) {
internalMerge(indexMetadata, reason, false);
internalMerge(indexMetadata, reason);
}

public DocumentMapper merge(String type, CompressedXContent mappingSource, MergeReason reason) {
return internalMerge(Collections.singletonMap(type, mappingSource), reason).get(type);
}

private synchronized Map<String, DocumentMapper> internalMerge(IndexMetadata indexMetadata,
MergeReason reason, boolean onlyUpdateIfNeeded) {
private synchronized Map<String, DocumentMapper> internalMerge(IndexMetadata indexMetadata, MergeReason reason) {
assert reason != MergeReason.MAPPING_UPDATE_PREFLIGHT;
Map<String, CompressedXContent> map = new LinkedHashMap<>();
for (ObjectCursor<MappingMetadata> cursor : indexMetadata.getMappings().values()) {
MappingMetadata mappingMetadata = cursor.value;
if (onlyUpdateIfNeeded) {
DocumentMapper existingMapper = documentMapper(mappingMetadata.type());
if (existingMapper == null || mappingMetadata.source().equals(existingMapper.mappingSource()) == false) {
map.put(mappingMetadata.type(), mappingMetadata.source());
}
} else {
map.put(mappingMetadata.type(), mappingMetadata.source());
}
map.put(mappingMetadata.type(), mappingMetadata.source());
}
return internalMerge(map, reason);
}
Expand Down

0 comments on commit 65f6fb8

Please sign in to comment.