浏览代码

Mapping: add an assertion to verify consistent serialization

We recently run into two issues where mapping weren't serialized in a consistent manner (#10302 and #10318). We rely on this consistency to do a byte level checl that mappings we get from the master are indentical to the one we have locally. Mistakes here can cause endless refresh mapping loops.

This commit adds an assert that verifies this upon every update from the master.
Boaz Leskes 10 年之前
父节点
当前提交
521f804c7d
共有 1 个文件被更改,包括 15 次插入0 次删除
  1. 15 0
      src/main/java/org/elasticsearch/index/mapper/MapperService.java

+ 15 - 0
src/main/java/org/elasticsearch/index/mapper/MapperService.java

@@ -267,6 +267,7 @@ public class MapperService extends AbstractIndexComponent  {
                     }
                 }
                 fieldDataService.onMappingUpdate();
+                assert assertSerialization(oldMapper);
                 return oldMapper;
             } else {
                 List<ObjectMapper> newObjectMappers = new ArrayList<>();
@@ -284,11 +285,25 @@ public class MapperService extends AbstractIndexComponent  {
                     typeListener.beforeCreate(mapper);
                 }
                 mappers = newMapBuilder(mappers).put(mapper.type(), mapper).map();
+                assert assertSerialization(mapper);
                 return mapper;
             }
         }
     }
 
+    private boolean assertSerialization(DocumentMapper mapper) {
+        // capture the source now, it may change due to concurrent parsing
+        final CompressedString mappingSource = mapper.mappingSource();
+        DocumentMapper newMapper = parse(mapper.type(), mappingSource, false);
+
+        if (newMapper.mappingSource().equals(mappingSource) == false) {
+            throw new IllegalStateException("DocumentMapper serialization result is different from source. \n--> Source ["
+                + mappingSource + "]\n--> Result ["
+                + newMapper.mappingSource() + "]");
+        }
+        return true;
+    }
+
     protected void addObjectMappers(Collection<ObjectMapper> objectMappers) {
         assert mappingLock.isWriteLockedByCurrentThread();
         ImmutableOpenMap.Builder<String, ObjectMappers> fullPathObjectMappers = ImmutableOpenMap.builder(this.fullPathObjectMappers);