Kaynağa Gözat

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 yıl önce
ebeveyn
işleme
521f804c7d

+ 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);