You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Manuel Núñez (Jira)" <ji...@apache.org> on 2021/03/14 09:46:00 UTC

[jira] [Updated] (IGNITE-14312) Ignite Client: Cannot find metadata for object with compact footer using SQL queries having multiple ignite client instances connected to different clusters within same application

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

Manuel Núñez updated IGNITE-14312:
----------------------------------
    Summary: Ignite Client: Cannot find metadata for object with compact footer using SQL queries having multiple ignite client instances connected to different clusters within same application  (was: Ignite Client: Cannot find metadata for object with compact footer using SQL queries having multiple ignite client instances connected to different clusters within sample application)

> Ignite Client: Cannot find metadata for object with compact footer using SQL queries having multiple ignite client instances connected to different clusters within same application
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: IGNITE-14312
>                 URL: https://issues.apache.org/jira/browse/IGNITE-14312
>             Project: Ignite
>          Issue Type: Bug
>          Components: binary, sql
>    Affects Versions: 2.6, 2.7, 2.8, 2.9
>            Reporter: Manuel Núñez
>            Priority: Blocker
>
> Application with multiple Ignite client instances connected to different clusters with enabled indexing module fails to deserialise SQL query response.
> 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 incorrect due to static use of JdbcUtils.serializer replaced by last IgniteH2Indexing instance on 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)