[jira] [Created] (IGNITE-14312) Ignite Client: Cannot find metadata for object with compact footer

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[jira] [Created] (IGNITE-14312) Ignite Client: Cannot find metadata for object with compact footer

Anton Vinogradov (Jira)
Manuel Núñez created IGNITE-14312:
-------------------------------------

             Summary: Ignite Client: Cannot find metadata for object with compact footer
                 Key: IGNITE-14312
                 URL: https://issues.apache.org/jira/browse/IGNITE-14312
             Project: Ignite
          Issue Type: Bug
          Components: binary
    Affects Versions: 2.9, 2.8, 2.7, 2.6
            Reporter: Manuel Núñez


Application with multiple Ignite client instances connected to different clusters with indexing module enable fails to reduce queries.

This is the exception:
{code:java}
Caused by: org.apache.ignite.binary.BinaryObjectException: Cannot find metadata for object with compact footer (Ignite work directory might have been cleared after restart. Make sure that IGNITE_HOME does not point to a temp folder or any other folder that is destroyed/cleared on restarts) [typeId=-1468802099, schemaId=360499151, IGNITE_HOME=/opt/ignite]
        at org.apache.ignite.internal.binary.BinaryReaderExImpl.getOrCreateSchema(BinaryReaderExImpl.java:2026) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.binary.BinaryReaderExImpl.<init>(BinaryReaderExImpl.java:293) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.binary.BinaryReaderExImpl.<init>(BinaryReaderExImpl.java:188) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.binary.BinaryObjectImpl.reader(BinaryObjectImpl.java:826) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:789) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.binary.BinaryObjectImpl.value(BinaryObjectImpl.java:142) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinary(CacheObjectUtils.java:176) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinaryIfNeeded(CacheObjectUtils.java:67) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinariesIfNeeded(CacheObjectUtils.java:135) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinariesIfNeeded(CacheObjectUtils.java:77) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator.next(GridQueryCacheObjectsIterator.java:66) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator.next(GridQueryCacheObjectsIterator.java:31) ~[ignite-core-2.8.1.jar!/:2.8.1]
        at org.apache.ignite.internal.processors.cache.AutoClosableCursorIterator.next(AutoClosableCursorIterator.java:59) ~[ignite-core-2.8.1.jar!/:2.8.1]
{code}

The error has been identified: Injected BinaryContext is invalid due to static use of JdbcUtils.serializer replaced into IgniteH2Indexing start method.

Solution: Use h2 DataHandler associated to GridKernalContext when calling ValueJavaObject.getNoCopy, this avoid using static Jdbc.serializer instance that could be eventually incorrect.

Proposal. Some simple changes into:
org.apache.ignite.internal.processors.query.h2.H2Utils
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing
org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2JavaObject
org.apache.ignite.internal.processors.query.h2.opt.GridH2ValueCacheObject


org.apache.ignite.internal.processors.query.h2.H2Utils:

{code:java}

    @SuppressWarnings("ConstantConditions")
    public static Value wrap(CacheObjectValueContext coCtx, Object obj, int type) throws IgniteCheckedException {
        assert obj != null;

....

            case Value.JAVA_OBJECT:
                return ValueJavaObject.getNoCopy(obj, null, coCtx == null ? null: H2Utils.getH2Datahandler(coCtx.kernalContext()));

...
}


    public static DataHandler getH2Datahandler(GridKernalContext ctx) {
        if (ctx == null)
            return null;

        return ((IgniteH2Indexing)ctx.query().getIndexing()).h2Datahandler();
    }

    public static JavaObjectSerializer getH2Serializer(GridKernalContext ctx) {
        if (ctx == null)
            return null;

        return ((IgniteH2Indexing)ctx.query().getIndexing()).h2Serializer();
    }

    public static DataHandler createH2Datahandler(GridKernalContext ctx) {
        return createH2Datahandler(createH2Serializer(ctx));
    }


    public static DataHandler createH2Datahandler(JavaObjectSerializer serializer) {
        return new DataHandler() {
            @Override
            public String getDatabasePath() {
                throw new UnsupportedOperationException();
            }

            @Override
            public FileStore openFile(String name, String mode, boolean mustExist) {
                throw new UnsupportedOperationException();
            }

            @Override
            public void checkPowerOff() throws DbException {
                throw new UnsupportedOperationException();
            }

            @Override
            public void checkWritingAllowed() throws DbException {
                throw new UnsupportedOperationException();
            }

            @Override
            public int getMaxLengthInplaceLob() {
                throw new UnsupportedOperationException();
            }

            @Override
            public String getLobCompressionAlgorithm(int type) {
                throw new UnsupportedOperationException();
            }

            @Override
            public TempFileDeleter getTempFileDeleter() {
                throw new UnsupportedOperationException();
            }

            @Override
            public Object getLobSyncObject() {
                throw new UnsupportedOperationException();
            }

            @Override
            public SmallLRUCache<String, String[]> getLobFileListCache() {
                throw new UnsupportedOperationException();
            }

            @Override
            public LobStorageInterface getLobStorage() {
                throw new UnsupportedOperationException();
            }

            @Override
            public int readLob(long lobId, byte[] hmac, long offset, byte[] buff, int off, int length) {
                throw new UnsupportedOperationException();
            }

            @Override
            public JavaObjectSerializer getJavaObjectSerializer() {
                return serializer;
            }

            @Override
            public CompareMode getCompareMode() {
                throw new UnsupportedOperationException();
            }
        };
    }

    public static JavaObjectSerializer createH2Serializer(GridKernalContext ctx) {
        return new JavaObjectSerializer() {
            @Override
            public byte[] serialize(Object obj) throws Exception {
                return U.marshal(ctx.config().getMarshaller(), obj);
            }

            @Override
            public Object deserialize(byte[] bytes) throws Exception {
                ClassLoader clsLdr = ctx != null ? U.resolveClassLoader(ctx.config()) : null;
                return U.unmarshal(ctx.config().getMarshaller(), bytes, clsLdr);
            }
        };
    }
{code}


org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing:

{code:java}

 ...
    private volatile DataHandler h2Datahandler;

    private volatile JavaObjectSerializer h2Serializer;

   ...

    /**
     * @return H2 datahandler.
     */
    public DataHandler h2Datahandler(){
        return h2Datahandler;
    }

    /**
     * @return H2 serializer.
     */
    public JavaObjectSerializer h2Serializer(){
        return h2Serializer;
    }

    @Override public void start(GridKernalContext ctx, GridSpinBusyLock busyLock) throws IgniteCheckedException {

...

        h2Serializer = H2Utils.createH2Serializer(ctx);
        h2Datahandler = H2Utils.createH2Datahandler(h2Serializer);

        if (JdbcUtils.serializer != null)
            U.warn(log, "Custom H2 serialization is already configured, will override.");


        JdbcUtils.serializer = h2Serializer;

...
}
{code}

org.apache.ignite.internal.processors.query.h2.opt.GridH2ValueCacheObject:

{code:java}
...
    @Override public byte[] getBytesNoCopy() {
        if (obj.cacheObjectType() == CacheObject.TYPE_REGULAR) {
            // Result must be the same as `marshaller.marshall(obj.value(coctx, false));`
            try {
                return obj.valueBytes(valCtx);
            }
            catch (IgniteCheckedException e) {
                throw DbException.convert(e);
            }
        }

        // For user-provided and array types.
        return JdbcUtils.serialize(obj, valCtx == null ? null: H2Utils.getH2Datahandler(valCtx.kernalContext()));
    }
{code}

org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2JavaObject:

{code:java}

...

    /** {@inheritDoc} */
    @Override public Value value(GridKernalContext ctx) {
        return ValueJavaObject.getNoCopy(null, b, H2Utils.getH2Datahandler(ctx));
    }
{code}




--
This message was sent by Atlassian Jira
(v8.3.4#803005)