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)