[ 
https://issues.apache.org/jira/browse/IGNITE-16318?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Taras Ledkov updated IGNITE-16318:
----------------------------------
    Description: 
Cache interceptor cause problem of missing binary scheme if sql insert contains 
only entry key fields and no one value field pass in query.
There is exception happened if inside interceptor we try to make 
BinaryObjectBuilder from entry value BinaryObject (#toBuilder()) and then 
request builder for any field.

Interceptor example:
{code:java}
new CacheInterceptorAdapter<BinaryObject, BinaryObject>() {
    @Nullable
    @Override public BinaryObject onBeforePut(Cache.Entry<BinaryObject, 
BinaryObject> entry, BinaryObject newVal) {
        BinaryObjectBuilder newValBuilder = newVal.toBuilder();
        String bValue = newValBuilder.getField("B"); // Cannot find schema for 
object with compact footer
        // ...
    }
} {code}
It's a pretty serious error which currupt and shutdown grid.

Code example:
{code:java}
LinkedHashMap<String, String> fields = new LinkedHashMap<>();
fields.put("A", "java.lang.String");
fields.put("B", "java.lang.String");
fields.put("C", "java.lang.String");

Set<String> keyFields = new LinkedHashSet<>();
keyFields.add("A");

CacheInterceptorAdapter cacheInterceptorAdapter = new 
CacheInterceptorAdapter<BinaryObject, BinaryObject>() {
    @Nullable
    @Override public BinaryObject onBeforePut(Cache.Entry<BinaryObject, 
BinaryObject> entry, BinaryObject newVal) {
        BinaryObjectBuilder newValBuilder = newVal.toBuilder();
        String bValue = newValBuilder.getField("B"); // Cannot find schema for 
object with compact footer
        if (bValue == null || bValue.isEmpty()) {
            newValBuilder.setField("B", "Some value");
        }
        return newValBuilder.build();
    }
};

CacheConfiguration cacheConfiguration = new CacheConfiguration<>()
        .setName("TEST_CACHE")
        .setKeyConfiguration(new CacheKeyConfiguration()
                .setTypeName("TEST_CACHE_KEY")
                .setAffinityKeyFieldName("InternalId"))
        .setQueryEntities(Collections.singleton(new QueryEntity()
                .setTableName("TEST_CACHE")
                .setKeyType("TEST_CACHE_KEY")
                .setValueType("TEST_CACHE_VALUE")
                .setFields(fields)
                .setKeyFields(keyFields)))
        .setInterceptor(cacheInterceptorAdapter);
IgniteConfiguration igniteConfiguration = new IgniteConfiguration()
        .setCacheConfiguration(cacheConfiguration);
try (Ignite ignite = Ignition.start(igniteConfiguration)) {
    IgniteCache testCache = ignite.getOrCreateCache("TEST_CACHE");
    // putSql
    testCache.query(new SqlFieldsQuery("INSERT INTO TEST_CACHE (A) VALUES 
('1234')"));
}{code}
Exception:
{code:java}
[2022-01-18 13:12:32,727][ERROR][main][CacheObjectBinaryProcessorImpl] Timed 
out while waiting for schema update [typeId=1147851335, schemaId=0]
[2022-01-18 13:12:32,730][ERROR][main][root] Critical system error detected. 
Will be handled accordingly to configured handler 
[hnd=StopNodeOrHaltFailureHandler [tryStop=false, timeout=0, 
super=AbstractFailureHandler [ignoredFailureTypes=UnmodifiableSet 
[SYSTEM_WORKER_BLOCKED, SYSTEM_CRITICAL_OPERATION_TIMEOUT]]], 
failureCtx=FailureContext [type=CRITICAL_ERROR, err=class 
o.a.i.i.processors.cache.persistence.tree.CorruptedTreeException: B+Tree is 
corrupted [groupId=-838655627, pageIds=[844420635166307], msg=Runtime failure 
on search row: SearchRow [key=TEST_CACHE_KEY [idHash=100929741, 
hash=-639470899, A=123], hash=-639470899, cacheId=0]]]]
class 
org.apache.ignite.internal.processors.cache.persistence.tree.CorruptedTreeException:
 B+Tree is corrupted [groupId=-838655627, pageIds=[844420635166307], 
msg=Runtime failure on search row: SearchRow [key=TEST_CACHE_KEY 
[idHash=100929741, hash=-639470899, A=123], hash=-639470899, cacheId=0]]
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.corruptedTreeException(BPlusTree.java:6237)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1988)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke0(IgniteCacheOffheapManagerImpl.java:1742)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke(IgniteCacheOffheapManagerImpl.java:1725)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl.invoke(IgniteCacheOffheapManagerImpl.java:449)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerUpdate(GridCacheMapEntry.java:2331)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateSingle(GridDhtAtomicCache.java:2553)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.update(GridDhtAtomicCache.java:2016)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal0(GridDhtAtomicCache.java:1833)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal(GridDhtAtomicCache.java:1692)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicAbstractUpdateFuture.sendSingleRequest(GridNearAtomicAbstractUpdateFuture.java:300)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateFuture.map(GridNearAtomicSingleUpdateFuture.java:481)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateFuture.mapOnTopology(GridNearAtomicSingleUpdateFuture.java:441)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicAbstractUpdateFuture.map(GridNearAtomicAbstractUpdateFuture.java:249)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.update0(GridDhtAtomicCache.java:1147)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.put0(GridDhtAtomicCache.java:615)
    at 
org.apache.ignite.internal.processors.cache.GridCacheAdapter.put(GridCacheAdapter.java:2571)
    at 
org.apache.ignite.internal.processors.cache.GridCacheAdapter.putIfAbsent(GridCacheAdapter.java:3018)
    at 
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.dmlDoInsert(DmlUtils.java:209)
    at 
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.processSelectResult(DmlUtils.java:175)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateNonTransactional(IgniteH2Indexing.java:2903)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdate(IgniteH2Indexing.java:2748)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateDistributed(IgniteH2Indexing.java:2674)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeDml(IgniteH2Indexing.java:1260)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.querySqlFields(IgniteH2Indexing.java:1182)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:2883)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:2879)
    at 
org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:3478)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.lambda$querySqlFields$3(GridQueryProcessor.java:2899)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuerySafe(GridQueryProcessor.java:2934)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2873)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2800)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:839)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:787)
    at 
org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.query(GatewayProtectedCacheProxy.java:430)
    at org.apache.ignite.examples.BBExample.main(BBExample.java:61)
Caused by: class org.apache.ignite.binary.BinaryObjectException: Cannot find 
schema for object with compact footer [typeName=TEST_CACHE_VALUE, 
typeId=1147851335, missingSchemaId=0, existingSchemaIds=[-2128831035]]
    at 
org.apache.ignite.internal.binary.BinaryReaderExImpl.getOrCreateSchema(BinaryReaderExImpl.java:2044)
    at 
org.apache.ignite.internal.binary.builder.BinaryBuilderReader.schema(BinaryBuilderReader.java:117)
    at 
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.ensureReadCacheInit(BinaryObjectBuilderImpl.java:497)
    at 
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.getField(BinaryObjectBuilderImpl.java:553)
    at org.apache.ignite.examples.BBExample$1.onBeforePut(BBExample.java:39)
    at org.apache.ignite.examples.BBExample$1.onBeforePut(BBExample.java:35)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.update(GridCacheMapEntry.java:6441)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.call(GridCacheMapEntry.java:6243)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.call(GridCacheMapEntry.java:5927)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.invokeClosure(BPlusTree.java:4093)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.access$5200(BPlusTree.java:3987)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invokeDown(BPlusTree.java:2065)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1955)
    ... 35 more
[2022-01-18 13:12:32,731][ERROR][main][FailureProcessor] A critical problem 
with in-memory data structures was detected.
[2022-01-18 13:12:32,731][ERROR][main][FailureProcessor] No deadlocked threads 
detected.
[2022-01-18 13:12:32,746][ERROR][main][FailureProcessor] Thread dump at 
2022/01/18 13:12:32 MSK {code}

*Root cause:*
The empty binary object is created invalid:
- with invalid schema: zero value insead of `BinaryUtils#schemaInitialId`
- with invalid offset: zero value instead of lenght of the header. It's a cause 
of invalid modification the empty object by builder.

  was:
Cache interceptor cause problem of missing binary scheme if sql insert contains 
only entry key fields and no one value field pass in query.
There is exception happened if inside interceptor we try to make 
BinaryObjectBuilder from entry value BinaryObject (#toBuilder()) and then 
request builder for any field.

Interceptor example:
{code:java}
new CacheInterceptorAdapter<BinaryObject, BinaryObject>() {
    @Nullable
    @Override public BinaryObject onBeforePut(Cache.Entry<BinaryObject, 
BinaryObject> entry, BinaryObject newVal) {
        BinaryObjectBuilder newValBuilder = newVal.toBuilder();
        String bValue = newValBuilder.getField("B"); // Cannot find schema for 
object with compact footer
        // ...
    }
} {code}
It's a pretty serious error which currupt and shutdown grid.

Code example:
{code:java}
LinkedHashMap<String, String> fields = new LinkedHashMap<>();
fields.put("A", "java.lang.String");
fields.put("B", "java.lang.String");
fields.put("C", "java.lang.String");

Set<String> keyFields = new LinkedHashSet<>();
keyFields.add("A");

CacheInterceptorAdapter cacheInterceptorAdapter = new 
CacheInterceptorAdapter<BinaryObject, BinaryObject>() {
    @Nullable
    @Override public BinaryObject onBeforePut(Cache.Entry<BinaryObject, 
BinaryObject> entry, BinaryObject newVal) {
        BinaryObjectBuilder newValBuilder = newVal.toBuilder();
        String bValue = newValBuilder.getField("B"); // Cannot find schema for 
object with compact footer
        if (bValue == null || bValue.isEmpty()) {
            newValBuilder.setField("B", "Some value");
        }
        return newValBuilder.build();
    }
};

CacheConfiguration cacheConfiguration = new CacheConfiguration<>()
        .setName("TEST_CACHE")
        .setKeyConfiguration(new CacheKeyConfiguration()
                .setTypeName("TEST_CACHE_KEY")
                .setAffinityKeyFieldName("InternalId"))
        .setQueryEntities(Collections.singleton(new QueryEntity()
                .setTableName("TEST_CACHE")
                .setKeyType("TEST_CACHE_KEY")
                .setValueType("TEST_CACHE_VALUE")
                .setFields(fields)
                .setKeyFields(keyFields)))
        .setInterceptor(cacheInterceptorAdapter);
IgniteConfiguration igniteConfiguration = new IgniteConfiguration()
        .setCacheConfiguration(cacheConfiguration);
try (Ignite ignite = Ignition.start(igniteConfiguration)) {
    IgniteCache testCache = ignite.getOrCreateCache("TEST_CACHE");
    // putSql
    testCache.query(new SqlFieldsQuery("INSERT INTO TEST_CACHE (A) VALUES 
('1234')"));
}{code}
Exception:
{code:java}
[2022-01-18 13:12:32,727][ERROR][main][CacheObjectBinaryProcessorImpl] Timed 
out while waiting for schema update [typeId=1147851335, schemaId=0]
[2022-01-18 13:12:32,730][ERROR][main][root] Critical system error detected. 
Will be handled accordingly to configured handler 
[hnd=StopNodeOrHaltFailureHandler [tryStop=false, timeout=0, 
super=AbstractFailureHandler [ignoredFailureTypes=UnmodifiableSet 
[SYSTEM_WORKER_BLOCKED, SYSTEM_CRITICAL_OPERATION_TIMEOUT]]], 
failureCtx=FailureContext [type=CRITICAL_ERROR, err=class 
o.a.i.i.processors.cache.persistence.tree.CorruptedTreeException: B+Tree is 
corrupted [groupId=-838655627, pageIds=[844420635166307], msg=Runtime failure 
on search row: SearchRow [key=TEST_CACHE_KEY [idHash=100929741, 
hash=-639470899, A=123], hash=-639470899, cacheId=0]]]]
class 
org.apache.ignite.internal.processors.cache.persistence.tree.CorruptedTreeException:
 B+Tree is corrupted [groupId=-838655627, pageIds=[844420635166307], 
msg=Runtime failure on search row: SearchRow [key=TEST_CACHE_KEY 
[idHash=100929741, hash=-639470899, A=123], hash=-639470899, cacheId=0]]
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.corruptedTreeException(BPlusTree.java:6237)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1988)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke0(IgniteCacheOffheapManagerImpl.java:1742)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke(IgniteCacheOffheapManagerImpl.java:1725)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl.invoke(IgniteCacheOffheapManagerImpl.java:449)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerUpdate(GridCacheMapEntry.java:2331)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateSingle(GridDhtAtomicCache.java:2553)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.update(GridDhtAtomicCache.java:2016)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal0(GridDhtAtomicCache.java:1833)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal(GridDhtAtomicCache.java:1692)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicAbstractUpdateFuture.sendSingleRequest(GridNearAtomicAbstractUpdateFuture.java:300)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateFuture.map(GridNearAtomicSingleUpdateFuture.java:481)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateFuture.mapOnTopology(GridNearAtomicSingleUpdateFuture.java:441)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicAbstractUpdateFuture.map(GridNearAtomicAbstractUpdateFuture.java:249)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.update0(GridDhtAtomicCache.java:1147)
    at 
org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.put0(GridDhtAtomicCache.java:615)
    at 
org.apache.ignite.internal.processors.cache.GridCacheAdapter.put(GridCacheAdapter.java:2571)
    at 
org.apache.ignite.internal.processors.cache.GridCacheAdapter.putIfAbsent(GridCacheAdapter.java:3018)
    at 
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.dmlDoInsert(DmlUtils.java:209)
    at 
org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.processSelectResult(DmlUtils.java:175)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateNonTransactional(IgniteH2Indexing.java:2903)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdate(IgniteH2Indexing.java:2748)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateDistributed(IgniteH2Indexing.java:2674)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeDml(IgniteH2Indexing.java:1260)
    at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.querySqlFields(IgniteH2Indexing.java:1182)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:2883)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:2879)
    at 
org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:3478)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.lambda$querySqlFields$3(GridQueryProcessor.java:2899)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuerySafe(GridQueryProcessor.java:2934)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2873)
    at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2800)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:839)
    at 
org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:787)
    at 
org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.query(GatewayProtectedCacheProxy.java:430)
    at org.apache.ignite.examples.BBExample.main(BBExample.java:61)
Caused by: class org.apache.ignite.binary.BinaryObjectException: Cannot find 
schema for object with compact footer [typeName=TEST_CACHE_VALUE, 
typeId=1147851335, missingSchemaId=0, existingSchemaIds=[-2128831035]]
    at 
org.apache.ignite.internal.binary.BinaryReaderExImpl.getOrCreateSchema(BinaryReaderExImpl.java:2044)
    at 
org.apache.ignite.internal.binary.builder.BinaryBuilderReader.schema(BinaryBuilderReader.java:117)
    at 
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.ensureReadCacheInit(BinaryObjectBuilderImpl.java:497)
    at 
org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.getField(BinaryObjectBuilderImpl.java:553)
    at org.apache.ignite.examples.BBExample$1.onBeforePut(BBExample.java:39)
    at org.apache.ignite.examples.BBExample$1.onBeforePut(BBExample.java:35)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.update(GridCacheMapEntry.java:6441)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.call(GridCacheMapEntry.java:6243)
    at 
org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.call(GridCacheMapEntry.java:5927)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.invokeClosure(BPlusTree.java:4093)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.access$5200(BPlusTree.java:3987)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invokeDown(BPlusTree.java:2065)
    at 
org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1955)
    ... 35 more
[2022-01-18 13:12:32,731][ERROR][main][FailureProcessor] A critical problem 
with in-memory data structures was detected.
[2022-01-18 13:12:32,731][ERROR][main][FailureProcessor] No deadlocked threads 
detected.
[2022-01-18 13:12:32,746][ERROR][main][FailureProcessor] Thread dump at 
2022/01/18 13:12:32 MSK {code}


> Empty binary object is incorrect written/read/modified
> ------------------------------------------------------
>
>                 Key: IGNITE-16318
>                 URL: https://issues.apache.org/jira/browse/IGNITE-16318
>             Project: Ignite
>          Issue Type: Bug
>          Components: binary, cache
>            Reporter: Andrey Belyaev
>            Assignee: Taras Ledkov
>            Priority: Major
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Cache interceptor cause problem of missing binary scheme if sql insert 
> contains only entry key fields and no one value field pass in query.
> There is exception happened if inside interceptor we try to make 
> BinaryObjectBuilder from entry value BinaryObject (#toBuilder()) and then 
> request builder for any field.
> Interceptor example:
> {code:java}
> new CacheInterceptorAdapter<BinaryObject, BinaryObject>() {
>     @Nullable
>     @Override public BinaryObject onBeforePut(Cache.Entry<BinaryObject, 
> BinaryObject> entry, BinaryObject newVal) {
>         BinaryObjectBuilder newValBuilder = newVal.toBuilder();
>         String bValue = newValBuilder.getField("B"); // Cannot find schema 
> for object with compact footer
>         // ...
>     }
> } {code}
> It's a pretty serious error which currupt and shutdown grid.
> Code example:
> {code:java}
> LinkedHashMap<String, String> fields = new LinkedHashMap<>();
> fields.put("A", "java.lang.String");
> fields.put("B", "java.lang.String");
> fields.put("C", "java.lang.String");
> Set<String> keyFields = new LinkedHashSet<>();
> keyFields.add("A");
> CacheInterceptorAdapter cacheInterceptorAdapter = new 
> CacheInterceptorAdapter<BinaryObject, BinaryObject>() {
>     @Nullable
>     @Override public BinaryObject onBeforePut(Cache.Entry<BinaryObject, 
> BinaryObject> entry, BinaryObject newVal) {
>         BinaryObjectBuilder newValBuilder = newVal.toBuilder();
>         String bValue = newValBuilder.getField("B"); // Cannot find schema 
> for object with compact footer
>         if (bValue == null || bValue.isEmpty()) {
>             newValBuilder.setField("B", "Some value");
>         }
>         return newValBuilder.build();
>     }
> };
> CacheConfiguration cacheConfiguration = new CacheConfiguration<>()
>         .setName("TEST_CACHE")
>         .setKeyConfiguration(new CacheKeyConfiguration()
>                 .setTypeName("TEST_CACHE_KEY")
>                 .setAffinityKeyFieldName("InternalId"))
>         .setQueryEntities(Collections.singleton(new QueryEntity()
>                 .setTableName("TEST_CACHE")
>                 .setKeyType("TEST_CACHE_KEY")
>                 .setValueType("TEST_CACHE_VALUE")
>                 .setFields(fields)
>                 .setKeyFields(keyFields)))
>         .setInterceptor(cacheInterceptorAdapter);
> IgniteConfiguration igniteConfiguration = new IgniteConfiguration()
>         .setCacheConfiguration(cacheConfiguration);
> try (Ignite ignite = Ignition.start(igniteConfiguration)) {
>     IgniteCache testCache = ignite.getOrCreateCache("TEST_CACHE");
>     // putSql
>     testCache.query(new SqlFieldsQuery("INSERT INTO TEST_CACHE (A) VALUES 
> ('1234')"));
> }{code}
> Exception:
> {code:java}
> [2022-01-18 13:12:32,727][ERROR][main][CacheObjectBinaryProcessorImpl] Timed 
> out while waiting for schema update [typeId=1147851335, schemaId=0]
> [2022-01-18 13:12:32,730][ERROR][main][root] Critical system error detected. 
> Will be handled accordingly to configured handler 
> [hnd=StopNodeOrHaltFailureHandler [tryStop=false, timeout=0, 
> super=AbstractFailureHandler [ignoredFailureTypes=UnmodifiableSet 
> [SYSTEM_WORKER_BLOCKED, SYSTEM_CRITICAL_OPERATION_TIMEOUT]]], 
> failureCtx=FailureContext [type=CRITICAL_ERROR, err=class 
> o.a.i.i.processors.cache.persistence.tree.CorruptedTreeException: B+Tree is 
> corrupted [groupId=-838655627, pageIds=[844420635166307], msg=Runtime failure 
> on search row: SearchRow [key=TEST_CACHE_KEY [idHash=100929741, 
> hash=-639470899, A=123], hash=-639470899, cacheId=0]]]]
> class 
> org.apache.ignite.internal.processors.cache.persistence.tree.CorruptedTreeException:
>  B+Tree is corrupted [groupId=-838655627, pageIds=[844420635166307], 
> msg=Runtime failure on search row: SearchRow [key=TEST_CACHE_KEY 
> [idHash=100929741, hash=-639470899, A=123], hash=-639470899, cacheId=0]]
>     at 
> org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.corruptedTreeException(BPlusTree.java:6237)
>     at 
> org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1988)
>     at 
> org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke0(IgniteCacheOffheapManagerImpl.java:1742)
>     at 
> org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$CacheDataStoreImpl.invoke(IgniteCacheOffheapManagerImpl.java:1725)
>     at 
> org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl.invoke(IgniteCacheOffheapManagerImpl.java:449)
>     at 
> org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerUpdate(GridCacheMapEntry.java:2331)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateSingle(GridDhtAtomicCache.java:2553)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.update(GridDhtAtomicCache.java:2016)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal0(GridDhtAtomicCache.java:1833)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateAllAsyncInternal(GridDhtAtomicCache.java:1692)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicAbstractUpdateFuture.sendSingleRequest(GridNearAtomicAbstractUpdateFuture.java:300)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateFuture.map(GridNearAtomicSingleUpdateFuture.java:481)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicSingleUpdateFuture.mapOnTopology(GridNearAtomicSingleUpdateFuture.java:441)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicAbstractUpdateFuture.map(GridNearAtomicAbstractUpdateFuture.java:249)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.update0(GridDhtAtomicCache.java:1147)
>     at 
> org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.put0(GridDhtAtomicCache.java:615)
>     at 
> org.apache.ignite.internal.processors.cache.GridCacheAdapter.put(GridCacheAdapter.java:2571)
>     at 
> org.apache.ignite.internal.processors.cache.GridCacheAdapter.putIfAbsent(GridCacheAdapter.java:3018)
>     at 
> org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.dmlDoInsert(DmlUtils.java:209)
>     at 
> org.apache.ignite.internal.processors.query.h2.dml.DmlUtils.processSelectResult(DmlUtils.java:175)
>     at 
> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateNonTransactional(IgniteH2Indexing.java:2903)
>     at 
> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdate(IgniteH2Indexing.java:2748)
>     at 
> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeUpdateDistributed(IgniteH2Indexing.java:2674)
>     at 
> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeDml(IgniteH2Indexing.java:1260)
>     at 
> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.querySqlFields(IgniteH2Indexing.java:1182)
>     at 
> org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:2883)
>     at 
> org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:2879)
>     at 
> org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)
>     at 
> org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:3478)
>     at 
> org.apache.ignite.internal.processors.query.GridQueryProcessor.lambda$querySqlFields$3(GridQueryProcessor.java:2899)
>     at 
> org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuerySafe(GridQueryProcessor.java:2934)
>     at 
> org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2873)
>     at 
> org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2800)
>     at 
> org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:839)
>     at 
> org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:787)
>     at 
> org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.query(GatewayProtectedCacheProxy.java:430)
>     at org.apache.ignite.examples.BBExample.main(BBExample.java:61)
> Caused by: class org.apache.ignite.binary.BinaryObjectException: Cannot find 
> schema for object with compact footer [typeName=TEST_CACHE_VALUE, 
> typeId=1147851335, missingSchemaId=0, existingSchemaIds=[-2128831035]]
>     at 
> org.apache.ignite.internal.binary.BinaryReaderExImpl.getOrCreateSchema(BinaryReaderExImpl.java:2044)
>     at 
> org.apache.ignite.internal.binary.builder.BinaryBuilderReader.schema(BinaryBuilderReader.java:117)
>     at 
> org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.ensureReadCacheInit(BinaryObjectBuilderImpl.java:497)
>     at 
> org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.getField(BinaryObjectBuilderImpl.java:553)
>     at org.apache.ignite.examples.BBExample$1.onBeforePut(BBExample.java:39)
>     at org.apache.ignite.examples.BBExample$1.onBeforePut(BBExample.java:35)
>     at 
> org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.update(GridCacheMapEntry.java:6441)
>     at 
> org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.call(GridCacheMapEntry.java:6243)
>     at 
> org.apache.ignite.internal.processors.cache.GridCacheMapEntry$AtomicCacheUpdateClosure.call(GridCacheMapEntry.java:5927)
>     at 
> org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.invokeClosure(BPlusTree.java:4093)
>     at 
> org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree$Invoke.access$5200(BPlusTree.java:3987)
>     at 
> org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invokeDown(BPlusTree.java:2065)
>     at 
> org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree.invoke(BPlusTree.java:1955)
>     ... 35 more
> [2022-01-18 13:12:32,731][ERROR][main][FailureProcessor] A critical problem 
> with in-memory data structures was detected.
> [2022-01-18 13:12:32,731][ERROR][main][FailureProcessor] No deadlocked 
> threads detected.
> [2022-01-18 13:12:32,746][ERROR][main][FailureProcessor] Thread dump at 
> 2022/01/18 13:12:32 MSK {code}
> *Root cause:*
> The empty binary object is created invalid:
> - with invalid schema: zero value insead of `BinaryUtils#schemaInitialId`
> - with invalid offset: zero value instead of lenght of the header. It's a 
> cause of invalid modification the empty object by builder.



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

Reply via email to