You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Ivan Daschinskiy (Jira)" <ji...@apache.org> on 2020/05/14 14:27:00 UTC

[jira] [Issue Comment Deleted] (IGNITE-12898) Server node with CacheStore fails to re-join the cluster: Cannot enable read-through (loader or store is not provided) for cache

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

Ivan Daschinskiy updated IGNITE-12898:
--------------------------------------
    Comment: was deleted

(was: [~daradurvs] Could you please make a review? )

> Server node with CacheStore fails to re-join the cluster: Cannot enable read-through (loader or store is not provided) for cache
> --------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: IGNITE-12898
>                 URL: https://issues.apache.org/jira/browse/IGNITE-12898
>             Project: Ignite
>          Issue Type: Bug
>    Affects Versions: 2.8
>            Reporter: Alexey Kukushkin
>            Assignee: Ivan Daschinskiy
>            Priority: Major
>              Labels: sbcf
>             Fix For: 2.9
>
>          Time Spent: 1h 50m
>  Remaining Estimate: 0h
>
> If a cache with external persistence is dynamically created on a non-affinity node then the cache affinity node cannot join the cluster after restart.
> h2. Repro Steps
>  # Run an "empty" Ignite node where no cache is going to be started
>  # Run a cache affinity node having the "ROLE" attribute set to "DATA"
>  # Create the cache from the "empty" node and use a Node Filter to limit the cache to the "data" node. External persistence is configured for the cache.
>  # Restart the "data" node
> h3. Actual Result
> {{IgniteCheckedException: Cannot enable read-through (loader or store is not provided) for cache}}
> h2. Reproducer
> h3. Reproducer.java
> {code:java}
> public class Reproducer {
>     @Test
>     public void test() throws Exception {
>         final String DB_URL = "jdbc:h2:mem:test";
>         final String ENTITY_NAME = "Person";
>         Function<String, IgniteConfiguration> igniteCfgFactory = instanceName ->
>             new IgniteConfiguration()
>                 .setIgniteInstanceName(instanceName)
>                 .setDiscoverySpi(new TcpDiscoverySpi()
>                     .setIpFinder(new TcpDiscoveryVmIpFinder().setAddresses(Collections.singleton("127.0.0.1:47500")))
>                 );
>         // 1. Run an "empty" Ignite node where no cache is going to be started
>         try (Connection dbConn = DriverManager.getConnection(DB_URL, "sa", "");
>              Statement dbStmt = dbConn.createStatement();
>              Ignite emptyNode = Ignition.start(igniteCfgFactory.apply("emptyyNode"))) {
>             // 2. Run a "Person" cache affinity node having the "ROLE" attribute set to "DATA"
>             Map<String, Object> dataNodeAttrs = new HashMap<>(1);
>             dataNodeAttrs.put(DataNodeFilter.ATTR_NAME, DataNodeFilter.ATTR_VAL);
>             Ignite dataNode = Ignition.start(igniteCfgFactory.apply("dataNode").setUserAttributes(dataNodeAttrs));
>             // 3. Create the "Person" cache from the "empty" node and use a Node Filter to limit the cache to the
>             // "data" node. External persistence to the "Person" table in H2 DB is configured for the cache.
>             dbStmt.execute("CREATE TABLE " + ENTITY_NAME + " (id int PRIMARY KEY, name varchar)");
>             CacheJdbcPojoStoreFactory<Integer, BinaryObject> igniteStoreFactory = new CacheJdbcPojoStoreFactory<>();
>             igniteStoreFactory.setDataSourceFactory(() -> JdbcConnectionPool.create(DB_URL, "sa", ""))
>                 .setTypes(
>                     new JdbcType()
>                         .setCacheName(ENTITY_NAME)
>                         .setDatabaseTable(ENTITY_NAME)
>                         .setKeyType(Integer.class)
>                         .setValueType(ENTITY_NAME)
>                         .setKeyFields(new JdbcTypeField(java.sql.Types.INTEGER, "id", Integer.class, "id"))
>                         .setValueFields(
>                             new JdbcTypeField(java.sql.Types.INTEGER, "id", Integer.class, "id"),
>                             new JdbcTypeField(java.sql.Types.VARCHAR, "name", String.class, "name")
>                         )
>                 );
>             CacheConfiguration<Integer, BinaryObject> cacheCfg =
>                 new CacheConfiguration<Integer, BinaryObject>(ENTITY_NAME)
>                     .setCacheMode(CacheMode.REPLICATED)
>                     .setCacheStoreFactory(igniteStoreFactory)
>                     .setWriteThrough(true)
>                     .setReadThrough(true)
>                     .setNodeFilter(new DataNodeFilter());
>             emptyNode.createCache(cacheCfg).withKeepBinary();
>             // 4. Restart the "data" node
>             dataNode.close();
>             dataNode = Ignition.start(igniteCfgFactory.apply("node2").setUserAttributes(dataNodeAttrs));
>             dataNode.close();
>         }
>     }
>     private static class DataNodeFilter implements IgnitePredicate<ClusterNode> {
>         public static final String ATTR_NAME = "ROLE";
>         public static final String ATTR_VAL = "DATA";
>         @Override public boolean apply(ClusterNode node) {
>             Object role = node.attributes().get(ATTR_NAME);
>             return role != null && ATTR_VAL.equalsIgnoreCase(role.toString());
>         }
>     }
> }
> {code}
> h3. build.gradle
> {code:groovy}
> dependencies {
>     compile group: 'org.apache.ignite', name: 'ignite-core', version: '2.8.0'
>     compile group: 'com.h2database', name: 'h2', version: '1.4.200'
>     testCompile group: 'junit', name: 'junit', version: '4.12'
> }
> {code}
> h2. Workaround
> Create dynamic caches only on the affinity nodes or use "static" caches defined in ignite node configuration.
> h2. Stack Trace
> {code}
> class org.apache.ignite.IgniteCheckedException: Cannot enable read-through (loader or store is not provided) for cache: Person
> 	at org.apache.ignite.internal.processors.cache.ValidationOnNodeJoinUtils.validate(ValidationOnNodeJoinUtils.java:348)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.createCacheContext(GridCacheProcessor.java:1201)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareCacheContext(GridCacheProcessor.java:1995)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.lambda$prepareStartCaches$d40a1773$1(GridCacheProcessor.java:1830)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.lambda$prepareStartCaches$8(GridCacheProcessor.java:1754)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.lambda$prepareStartCaches$926b6886$1(GridCacheProcessor.java:1827)
> 	at org.apache.ignite.internal.util.IgniteUtils.doInParallel(IgniteUtils.java:11157)
> 	at org.apache.ignite.internal.util.IgniteUtils.doInParallel(IgniteUtils.java:11059)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareStartCaches(GridCacheProcessor.java:1822)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareStartCaches(GridCacheProcessor.java:1753)
> 	at org.apache.ignite.internal.processors.cache.GridCacheProcessor.startCachesOnLocalJoin(GridCacheProcessor.java:1699)
> 	at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.initCachesOnLocalJoin(GridDhtPartitionsExchangeFuture.java:994)
> 	at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.init(GridDhtPartitionsExchangeFuture.java:847)
> 	at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$ExchangeWorker.body0(GridCachePartitionExchangeManager.java:3172)
> 	at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$ExchangeWorker.body(GridCachePartitionExchangeManager.java:3021)
> 	at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:120)
> 	at java.base/java.lang.Thread.run(Thread.java:834)
> {code}



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