use of org.apache.ignite.cache.affinity.Affinity in project ignite by apache.
the class CacheMvccTxRecoveryTest method testUpdateCountersGapIsClosed.
/**
* @throws Exception if failed.
*/
@Test
public void testUpdateCountersGapIsClosed() throws Exception {
int srvCnt = 3;
startGridsMultiThreaded(srvCnt);
client = true;
IgniteEx ign = startGrid(srvCnt);
IgniteCache<Object, Object> cache = ign.getOrCreateCache(basicCcfg().setBackups(2));
int vid = 1;
IgniteEx victim = grid(vid);
ArrayList<Integer> keys = new ArrayList<>();
Integer part = null;
Affinity<Object> aff = ign.affinity(DEFAULT_CACHE_NAME);
for (int i = 0; i < 2000; i++) {
int p = aff.partition(i);
if (aff.isPrimary(victim.localNode(), i)) {
if (part == null)
part = p;
if (p == part)
keys.add(i);
if (keys.size() == 2)
break;
}
}
assert keys.size() == 2;
Transaction txA = ign.transactions().txStart(PESSIMISTIC, REPEATABLE_READ);
// prevent first transaction prepare on backups
((TestRecordingCommunicationSpi) victim.configuration().getCommunicationSpi()).blockMessages(new IgniteBiPredicate<ClusterNode, Message>() {
final AtomicInteger limiter = new AtomicInteger();
@Override
public boolean apply(ClusterNode node, Message msg) {
if (msg instanceof GridDhtTxPrepareRequest)
return limiter.getAndIncrement() < 2;
return false;
}
});
cache.query(new SqlFieldsQuery("insert into Integer(_key, _val) values(?, 42)").setArgs(keys.get(0)));
txA.commitAsync();
GridCacheVersion aXidVer = ((TransactionProxyImpl) txA).tx().xidVersion();
assertConditionEventually(() -> txsOnNode(victim, aXidVer).stream().anyMatch(tx -> tx.state() == PREPARING));
GridTestUtils.runAsync(() -> {
try (Transaction txB = ign.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
cache.query(new SqlFieldsQuery("insert into Integer(_key, _val) values(?, 42)").setArgs(keys.get(1)));
txB.commit();
}
}).get();
long victimUpdCntr = updateCounter(victim.cachex(DEFAULT_CACHE_NAME).context(), keys.get(0));
List<IgniteEx> backupNodes = grids(srvCnt, i -> i != vid);
List<IgniteInternalTx> backupTxsA = backupNodes.stream().map(node -> txsOnNode(node, aXidVer)).flatMap(Collection::stream).collect(Collectors.toList());
// drop primary
victim.close();
assertConditionEventually(() -> backupTxsA.stream().allMatch(tx -> tx.state() == ROLLED_BACK));
backupNodes.stream().map(node -> node.cache(DEFAULT_CACHE_NAME)).forEach(c -> {
assertEquals(1, c.query(new SqlFieldsQuery("select * from Integer")).getAll().size());
});
backupNodes.forEach(node -> {
for (Integer k : keys) assertEquals(victimUpdCntr, updateCounter(node.cachex(DEFAULT_CACHE_NAME).context(), k));
});
}
use of org.apache.ignite.cache.affinity.Affinity in project ignite by apache.
the class CacheMvccTxRecoveryTest method checkRecoveryPrimaryFailure.
/**
*/
private void checkRecoveryPrimaryFailure(TxEndResult endRes, boolean mvccCrd) throws Exception {
int gridCnt = 4;
int baseCnt = gridCnt - 1;
boolean commit = endRes == COMMIT;
startGridsMultiThreaded(baseCnt);
client = true;
IgniteEx nearNode = startGrid(baseCnt);
IgniteCache<Object, Object> cache = nearNode.getOrCreateCache(basicCcfg().setBackups(1));
Affinity<Object> aff = nearNode.affinity(DEFAULT_CACHE_NAME);
List<Integer> keys = new ArrayList<>();
for (int i = 0; i < 100; i++) {
if (aff.isPrimary(grid(0).localNode(), i) && aff.isBackup(grid(1).localNode(), i)) {
keys.add(i);
break;
}
}
for (int i = 0; i < 100; i++) {
if (aff.isPrimary(grid(1).localNode(), i) && aff.isBackup(grid(2).localNode(), i)) {
keys.add(i);
break;
}
}
assert keys.size() == 2;
int victim, victimBackup;
if (mvccCrd) {
victim = 0;
victimBackup = 1;
} else {
victim = 1;
victimBackup = 2;
}
TestRecordingCommunicationSpi victimComm = (TestRecordingCommunicationSpi) grid(victim).configuration().getCommunicationSpi();
if (commit)
victimComm.blockMessages(GridNearTxFinishResponse.class, nearNode.name());
else
victimComm.blockMessages(GridDhtTxPrepareRequest.class, grid(victimBackup).name());
GridNearTxLocal nearTx = ((TransactionProxyImpl) nearNode.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)).tx();
for (Integer k : keys) cache.query(new SqlFieldsQuery("insert into Integer(_key, _val) values(?, 42)").setArgs(k));
List<IgniteInternalTx> txs = IntStream.range(0, baseCnt).filter(i -> i != victim).mapToObj(i -> txsOnNode(grid(i), nearTx.xidVersion())).flatMap(Collection::stream).collect(Collectors.toList());
IgniteInternalFuture<IgniteInternalTx> commitFut = nearTx.commitAsync();
if (commit)
assertConditionEventually(() -> txs.stream().allMatch(tx -> tx.state() == COMMITTED));
else
assertConditionEventually(() -> txs.stream().anyMatch(tx -> tx.state() == PREPARED));
// drop victim
grid(victim).close();
awaitPartitionMapExchange();
assertConditionEventually(() -> txs.stream().allMatch(tx -> tx.state() == (commit ? COMMITTED : ROLLED_BACK)));
assert victimComm.hasBlockedMessages();
if (commit) {
assertConditionEventually(() -> {
int rowsCnt = G.allGrids().get(0).cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("select * from Integer")).getAll().size();
return rowsCnt == keys.size();
});
} else {
int rowsCnt = G.allGrids().get(0).cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("select * from Integer")).getAll().size();
assertEquals(0, rowsCnt);
}
assertTrue(commitFut.isDone());
assertPartitionCountersAreConsistent(keys, grids(baseCnt, i -> i != victim));
}
use of org.apache.ignite.cache.affinity.Affinity in project ignite by apache.
the class IgniteSqlSkipReducerOnUpdateDmlSelfTest method testSpecificPartitionsUpdate.
/**
* @throws Exception if failed.
*/
@Test
public void testSpecificPartitionsUpdate() throws Exception {
fillCaches();
Affinity aff = grid(NODE_CLIENT).affinity(CACHE_PERSON);
int numParts = aff.partitions();
int[] parts = new int[numParts / 2];
for (int idx = 0; idx < numParts / 2; idx++) parts[idx] = idx * 2;
IgniteCache<PersonKey, Person> cache = grid(NODE_CLIENT).cache(CACHE_PERSON);
// UPDATE over even partitions
cache.query(new SqlFieldsQueryEx("UPDATE Person SET position = 0", false).setSkipReducerOnUpdate(true).setPartitions(parts));
List<List<?>> rows = cache.query(new SqlFieldsQuery("SELECT _key, position FROM Person")).getAll();
for (List<?> row : rows) {
PersonKey personKey = (PersonKey) row.get(0);
int pos = ((Number) row.get(1)).intValue();
int part = aff.partition(personKey);
assertTrue((part % 2 == 0) ^ (pos != 0));
}
}
use of org.apache.ignite.cache.affinity.Affinity in project ignite by apache.
the class IgniteCacheConcurrentPutGetRemoveTest method putGetRemove.
/**
* @param ccfg Cache configuration.
* @throws Exception If failed.
*/
private void putGetRemove(final CacheConfiguration ccfg) throws Exception {
ignite(0).createCache(ccfg);
try {
long stopTime = System.currentTimeMillis() + 30_000;
int iter = 0;
while (System.currentTimeMillis() < stopTime) {
if (iter++ % 100 == 0)
log.info("Iteration: " + iter);
final AtomicInteger idx = new AtomicInteger();
final int KEYS = 10;
GridTestUtils.runMultiThreaded(new Callable<Void>() {
@Override
public Void call() throws Exception {
int nodeIdx = idx.getAndIncrement() % NODES;
IgniteCache<Object, Object> cache = ignite(nodeIdx).cache(ccfg.getName());
ThreadLocalRandom rnd = ThreadLocalRandom.current();
for (int i = 0; i < 10; i++) {
for (int k = 0; k < KEYS; k++) {
switch(rnd.nextInt(3)) {
case 0:
cache.put(k, rnd.nextInt(10_000));
break;
case 1:
cache.get(k);
break;
case 2:
cache.remove(k);
break;
default:
fail();
}
}
}
return null;
}
}, NODES * 10, "update-thread");
Affinity aff = ignite(0).affinity(ccfg.getName());
for (int k = 0; k < KEYS; k++) {
Collection<ClusterNode> nodes = aff.mapKeyToPrimaryAndBackups(k);
Object expVal = grid(nodes.iterator().next()).cache(ccfg.getName()).get(k);
for (int n = 0; n < NODES; n++) {
Ignite ignite = ignite(n);
IgniteCache<Object, Object> cache = ignite.cache(ccfg.getName());
if (nodes.contains(ignite.cluster().localNode()))
assertEquals(expVal, cache.localPeek(k));
else {
assertNull(cache.localPeek(k));
assertEquals(expVal, cache.get(k));
}
}
}
}
} finally {
ignite(0).destroyCache(ccfg.getName());
}
}
use of org.apache.ignite.cache.affinity.Affinity in project ignite by apache.
the class CacheMvccTransactionsTest method doImplicitPartsScanTest.
/**
* @param srvs Number of server nodes.
* @param clients Number of client nodes.
* @param cacheBackups Number of cache backups.
* @param cacheParts Number of cache partitions.
* @throws Exception If failed.
*/
private void doImplicitPartsScanTest(final int srvs, final int clients, int cacheBackups, int cacheParts) throws Exception {
final int KEYS_PER_PART = 20;
final int writers = 4;
final int readers = 4;
Map<Integer, List<Integer>> keysByParts = new HashMap<>();
final IgniteInClosure<IgniteCache<Object, Object>> init = new IgniteInClosure<IgniteCache<Object, Object>>() {
@Override
public void apply(IgniteCache<Object, Object> cache) {
final IgniteTransactions txs = cache.unwrap(Ignite.class).transactions();
for (int i = 0; i < cacheParts; i++) {
List<Integer> keys = new ArrayList<>();
keysByParts.put(i, keys);
}
Affinity aff = affinity(cache);
int cntr = 0;
int key = 0;
while (cntr < KEYS_PER_PART * cacheParts) {
int part = aff.partition(key);
List<Integer> keys = keysByParts.get(part);
if (keys.size() < KEYS_PER_PART) {
keys.add(key);
cntr++;
}
key++;
}
try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
for (List<Integer> keys : keysByParts.values()) for (Integer k : keys) cache.put(k, new MvccTestAccount(0, 1));
tx.commit();
}
}
};
GridInClosure3<Integer, List<TestCache>, AtomicBoolean> writer = new GridInClosure3<Integer, List<TestCache>, AtomicBoolean>() {
@Override
public void apply(Integer idx, List<TestCache> caches, AtomicBoolean stop) {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (!stop.get()) {
int part = rnd.nextInt(cacheParts);
List<Integer> partKeys = keysByParts.get(part);
TestCache<Integer, MvccTestAccount> cache = randomCache(caches, rnd);
IgniteTransactions txs = cache.cache.unwrap(Ignite.class).transactions();
Integer k1 = partKeys.get(rnd.nextInt(KEYS_PER_PART));
Integer k2 = partKeys.get(rnd.nextInt(KEYS_PER_PART));
while (k1.equals(k2)) k2 = partKeys.get(rnd.nextInt(KEYS_PER_PART));
if (k1 > k2) {
int tmp = k1;
k1 = k2;
k2 = tmp;
}
TreeSet<Integer> keys = new TreeSet<>();
keys.add(k1);
keys.add(k2);
try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
Map<Integer, MvccTestAccount> accs = cache.cache.getAll(keys);
MvccTestAccount acc1 = accs.get(k1);
MvccTestAccount acc2 = accs.get(k2);
assertNotNull(acc1);
assertNotNull(acc2);
cache.cache.put(k1, new MvccTestAccount(acc1.val + 1, acc1.updateCnt + 1));
cache.cache.put(k2, new MvccTestAccount(acc2.val - 1, acc2.updateCnt + 1));
tx.commit();
} catch (CacheException ex) {
MvccFeatureChecker.assertMvccWriteConflict(ex);
} finally {
cache.readUnlock();
}
}
}
};
GridInClosure3<Integer, List<TestCache>, AtomicBoolean> reader = new GridInClosure3<Integer, List<TestCache>, AtomicBoolean>() {
@Override
public void apply(Integer idx, List<TestCache> caches, AtomicBoolean stop) {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
while (!stop.get()) {
int part = rnd.nextInt(cacheParts);
TestCache<Integer, Integer> cache = randomCache(caches, rnd);
try {
Affinity aff = affinity(cache.cache);
ScanQuery<Integer, MvccTestAccount> qry = new ScanQuery<>(part);
List<Cache.Entry<Integer, MvccTestAccount>> res = cache.cache.query(qry).getAll();
int sum = 0;
for (Cache.Entry<Integer, MvccTestAccount> entry : res) {
Integer key = entry.getKey();
MvccTestAccount acc = entry.getValue();
assertEquals(part, aff.partition(key));
sum += acc.val;
}
assertEquals(0, sum);
} finally {
cache.readUnlock();
}
if (idx == 0) {
cache = randomCache(caches, rnd);
try {
ScanQuery<Integer, MvccTestAccount> qry = new ScanQuery<>();
List<Cache.Entry<Integer, MvccTestAccount>> res = cache.cache.query(qry).getAll();
int sum = 0;
for (Cache.Entry<Integer, MvccTestAccount> entry : res) {
Integer key = entry.getKey();
MvccTestAccount acc = entry.getValue();
sum += acc.val;
}
assertEquals(0, sum);
} finally {
cache.readUnlock();
}
}
}
}
};
readWriteTest(null, srvs, clients, cacheBackups, cacheParts, writers, readers, SCALED_10SEC_TEST_TIME, null, init, writer, reader);
}
Aggregations