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)