Never throw an IAE if the IndexMapper isn't present in PostingsFormat

If we throw an exception in the PostingsFormat during a merge we essentially
fail the entire merge which can lead to a corrupt index. We should rather
return the default postings format for the new segment and log a warning.

Closes #3088
This commit is contained in:
Simon Willnauer 2013-05-24 16:46:19 +02:00
parent 9ed274822d
commit 6e366bae34
2 changed files with 7 additions and 5 deletions

View File

@ -64,7 +64,7 @@ public class CodecService extends AbstractIndexComponent {
if (mapperService == null) {
codecs.put("default", Codec.getDefault());
} else {
codecs.put("default", new PerFieldMappingPostingFormatCodec(mapperService, postingsFormatService.get("default").get()));
codecs.put("default", new PerFieldMappingPostingFormatCodec(mapperService, postingsFormatService.get("default").get(), logger));
}
for (String codec : Codec.availableCodecs()) {
codecs.put(codec, Codec.forName(codec));

View File

@ -21,7 +21,7 @@ package org.elasticsearch.index.codec;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.lucene42.Lucene42Codec;
import org.elasticsearch.ElasticSearchIllegalStateException;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.index.codec.postingsformat.PostingsFormatProvider;
import org.elasticsearch.index.mapper.FieldMappers;
import org.elasticsearch.index.mapper.MapperService;
@ -36,12 +36,13 @@ import org.elasticsearch.index.mapper.MapperService;
*/
// LUCENE UPGRADE: make sure to move to a new codec depending on the lucene version
public class PerFieldMappingPostingFormatCodec extends Lucene42Codec {
private final ESLogger logger;
private final MapperService mapperService;
private final PostingsFormat defaultPostingFormat;
public PerFieldMappingPostingFormatCodec(MapperService mapperService, PostingsFormat defaultPostingFormat) {
public PerFieldMappingPostingFormatCodec(MapperService mapperService, PostingsFormat defaultPostingFormat, ESLogger logger) {
this.mapperService = mapperService;
this.logger = logger;
this.defaultPostingFormat = defaultPostingFormat;
}
@ -49,7 +50,8 @@ public class PerFieldMappingPostingFormatCodec extends Lucene42Codec {
public PostingsFormat getPostingsFormatForField(String field) {
final FieldMappers indexName = mapperService.indexName(field);
if (indexName == null) {
throw new ElasticSearchIllegalStateException("no index mapper found for field: [" + field + "]");
logger.warn("no index mapper found for field: [{}] returning default postings format", field);
return defaultPostingFormat;
}
PostingsFormatProvider postingsFormat = indexName.mapper().postingsFormatProvider();
return postingsFormat != null ? postingsFormat.get() : defaultPostingFormat;