use of org.apache.ignite.internal.processors.cache.PartitionUpdateCounter in project ignite by apache.
the class TxPartitionCounterStateOnePrimaryOneBackupTest method doTestPrepareCommitReorder_2.
/**
* Adds primary restart in the middle of rebalance.
*
* @param skipCheckpoint Skip checkpoint.
*/
private void doTestPrepareCommitReorder_2(boolean skipCheckpoint) throws Exception {
Map<Integer, T2<Ignite, List<Ignite>>> txTops = runTest(skipCheckpoint);
T2<Ignite, List<Ignite>> txTop = txTops.get(PARTITION_ID);
String primaryName = txTop.get1().name();
String backupName = txTop.get2().get(0).name();
IgniteEx client = grid(CLIENT_GRID_NAME);
waitForTopology(SERVERS_CNT);
// If not wait for PME backup might not switch to primary.
awaitPartitionMapExchange();
PartitionUpdateCounter cntr2 = counter(PARTITION_ID, backupName);
assertNotNull(cntr2);
assertEquals(TOTAL, cntr2.get());
assertEquals(TOTAL, cntr2.reserved());
assertTrue(cntr2.sequential());
assertEquals("Backup has not all committed transactions", TOTAL, client.cache(DEFAULT_CACHE_NAME).size());
TestRecordingCommunicationSpi.stopBlockAll();
TestRecordingCommunicationSpi backupSpi = TestRecordingCommunicationSpi.spi(grid(backupName));
backupSpi.blockMessages((node, msg) -> {
if (msg instanceof GridDhtPartitionSupplyMessage) {
GridDhtPartitionSupplyMessage m0 = (GridDhtPartitionSupplyMessage) msg;
return m0.groupId() == CU.cacheId(DEFAULT_CACHE_NAME);
}
return false;
});
// Restart primary during rebalance.
IgniteInternalFuture<?> fut = multithreadedAsync(() -> {
try {
backupSpi.waitForBlocked();
} catch (InterruptedException e) {
fail("Unexpected interruption");
}
stopGrid(skipCheckpoint, primaryName);
backupSpi.stopBlock();
try {
startGrid(primaryName);
awaitPartitionMapExchange();
} catch (Exception e) {
fail();
}
}, 1);
// Trigger rebalance.
IgniteEx prim = startGrid(primaryName);
// Wait for restart.
fut.get();
assertPartitionsSame(idleVerify(client, DEFAULT_CACHE_NAME));
}
use of org.apache.ignite.internal.processors.cache.PartitionUpdateCounter in project ignite by apache.
the class TxPartitionCounterStateOnePrimaryTwoBackupsTest method testCommitReorderWithRollbackNoRebalanceAfterRestart.
/**
* Test scenario:
* <p>
* 1. Assign counters in order tx0, tx1
* <p>
* 2. Commit tx1.
* <p>
* 3. Prepare tx0 on both backups.
* <p>
* 4. Stop primary to trigger rollback on recovery.
* <p>
* 5. Stop backup1 without triggering checkpoint.
* <p>
* 6. Start backup1.
*
* Pass condition: backup1 has RollbackRecord in WAL closing the gap on logical recovery.
* After logical recovery no rebalancing must happen.
*
* @throws Exception If failed.
*/
@Test
public void testCommitReorderWithRollbackNoRebalanceAfterRestart() throws Exception {
int[] sizes = new int[] { 3, 7 };
int[] assignOrder = new int[] { 0, 1 };
int[] prepOrder = new int[] { 1, 0 };
Map<Integer, T2<Ignite, List<Ignite>>> txTops = runOnPartition(PARTITION_ID, null, BACKUPS, SERVERS_CNT, map -> {
Ignite primary = map.get(PARTITION_ID).get1();
return new TwoPhaseCommitTxCallbackAdapter(U.map((IgniteEx) primary, assignOrder), U.map((IgniteEx) primary, prepOrder), new HashMap<>(), sizes.length) {
@Override
protected boolean onPrimaryPrepared(IgniteEx primary, IgniteInternalTx tx, int idx) {
super.onPrimaryPrepared(primary, tx, idx);
// Prevent preparing tx0 on primary.
return idx == prepOrder[0];
}
@Override
public boolean afterPrimaryFinish(IgniteEx primary, IgniteUuid nearXidVer, GridFutureAdapter<?> proceedFut) {
log.info("TX: Finish primary " + order(nearXidVer));
runAsync(() -> stopGrid(true, primary.name()));
return super.afterPrimaryFinish(primary, nearXidVer, proceedFut);
}
};
}, sizes);
// SERVERS_CNT - 1 + client node.
waitForTopology(SERVERS_CNT);
awaitPartitionMapExchange();
// No gaps are expected on backups.
Ignite backup1 = txTops.get(PARTITION_ID).get2().get(0);
Ignite backup2 = txTops.get(PARTITION_ID).get2().get(1);
IgniteEx client = grid(CLIENT_GRID_NAME);
assertPartitionsSame(idleVerify(client, DEFAULT_CACHE_NAME));
assertCountersSame(PARTITION_ID, true, DEFAULT_CACHE_NAME);
PartitionUpdateCounter cntr1 = counter(PARTITION_ID, backup1.name());
assertNotNull(cntr1);
assertTrue(cntr1.sequential());
PartitionUpdateCounter cntr2 = counter(PARTITION_ID, backup2.name());
assertNotNull(cntr2);
assertTrue(cntr2.sequential());
stopGrid(true, backup1.name());
// Prevent rebalance from backup2.
TestRecordingCommunicationSpi spi = TestRecordingCommunicationSpi.spi(backup2);
spi.record(GridDhtPartitionSupplyMessage.class);
startGrid(backup1.name());
awaitPartitionMapExchange();
assertTrue(spi.recordedMessages(true).isEmpty());
}
use of org.apache.ignite.internal.processors.cache.PartitionUpdateCounter in project ignite by apache.
the class TxPartitionCounterStateOnePrimaryTwoBackupsTest method doTestPartialCommit_3tx_1.
/**
* Test scenario:
* <p>
* 1. Prepare all txs.
* <p>
* 2. Fail backup1 after first commit.
* <p>
* 3. Start failed backup.
* <p>
* 4. Check if the backup is rebalanced correctly from primary node.
* <p>
* 5. Stop primary node.
* <p>
* 6. Put data to remaining nodes.
* <p>
* 7. Start primary node.
* <p>
* 8. Check if primary is rebalanced correctly from new primary node.
*
* @param skipCheckpointOnNodeStop Skip checkpoint on node stop.
* @throws Exception If failed.
*/
private void doTestPartialCommit_3tx_1(boolean skipCheckpointOnNodeStop) throws Exception {
Map<Integer, T2<Ignite, List<Ignite>>> txTops = runOnPartition(PARTITION_ID, null, BACKUPS, SERVERS_CNT, new IgniteClosure<Map<Integer, T2<Ignite, List<Ignite>>>, TxCallback>() {
@Override
public TxCallback apply(Map<Integer, T2<Ignite, List<Ignite>>> map) {
Ignite primary = map.get(PARTITION_ID).get1();
Ignite backup1 = map.get(PARTITION_ID).get2().get(0);
return new TwoPhaseCommitTxCallbackAdapter(U.map((IgniteEx) primary, PREPARE_ORDER), U.map((IgniteEx) primary, PRIMARY_COMMIT_ORDER, (IgniteEx) backup1, BACKUP_COMMIT_ORDER), SIZES.length) {
@Override
protected boolean onBackupCommitted(IgniteEx backup, int idx) {
super.onBackupCommitted(backup, idx);
if (idx == BACKUP_COMMIT_ORDER[0]) {
PartitionUpdateCounter cntr = counter(PARTITION_ID, backup.name());
assertNotNull(cntr);
assertFalse(cntr.sequential());
long[] upd = cntr.iterator().next();
assertEquals(PRELOAD_KEYS_CNT + SIZES[BACKUP_COMMIT_ORDER[1]] + SIZES[BACKUP_COMMIT_ORDER[2]], upd[0]);
assertEquals(SIZES[BACKUP_COMMIT_ORDER[0]], upd[1]);
runAsync(() -> {
// Will stop backup node before all commits are applied.
stopGrid(skipCheckpointOnNodeStop, backup.name());
});
return true;
}
throw new IgniteException("Should not commit other transactions");
}
};
}
}, SIZES);
T2<Ignite, List<Ignite>> txTop = txTops.get(PARTITION_ID);
waitForTopology(SERVERS_CNT);
awaitPartitionMapExchange();
IgniteEx client = grid(CLIENT_GRID_NAME);
assertEquals("Primary has not all committed transactions", TOTAL, client.cache(DEFAULT_CACHE_NAME).size());
for (Ignite ignite : G.allGrids()) TestRecordingCommunicationSpi.spi(ignite).stopBlock(false);
String backupName = txTop.get2().get(0).name();
IgniteEx backup = startGrid(backupName);
awaitPartitionMapExchange();
assertPartitionsSame(idleVerify(client, DEFAULT_CACHE_NAME));
PartitionUpdateCounter cntr = counter(PARTITION_ID, backup.name());
assertNotNull(cntr);
assertTrue(cntr.sequential());
assertEquals(TOTAL, cntr.get());
String primaryName = txTop.get1().name();
stopGrid(primaryName);
awaitPartitionMapExchange();
assertNotNull(cntr = counter(PARTITION_ID, backup.name()));
assertEquals(TOTAL, cntr.reserved());
// Make update to advance a counter.
int addCnt = 10;
loadDataToPartition(PARTITION_ID, backupName, DEFAULT_CACHE_NAME, addCnt, TOTAL);
// TODO https://issues.apache.org/jira/browse/IGNITE-11607
// Historical rebalance is not possible from checkpoint containing rebalance entries.
// Next rebalance will be full.
IgniteEx grid0 = startGrid(primaryName);
awaitPartitionMapExchange();
assertNotNull(cntr = counter(PARTITION_ID, grid0.name()));
assertEquals(TOTAL + addCnt, cntr.get());
assertEquals(TOTAL + addCnt, cntr.reserved());
assertPartitionsSame(idleVerify(client, DEFAULT_CACHE_NAME));
}
use of org.apache.ignite.internal.processors.cache.PartitionUpdateCounter in project ignite by apache.
the class TxPartitionCounterStateConsistencyTest method testPartitionConsistencyCancelledRebalanceCoordinatorIsDemander.
/**
* Tests reproduces the problem: if coordinator is a demander after activation and supplier has left, new
* rebalance will finish and cause no partition inconsistencies.
*
* @throws Exception If failed.
*/
@Test
public void testPartitionConsistencyCancelledRebalanceCoordinatorIsDemander() throws Exception {
backups = 2;
Ignite crd = startGrids(SERVER_NODES);
crd.cluster().active(true);
int[] primaryParts = crd.affinity(DEFAULT_CACHE_NAME).primaryPartitions(crd.cluster().localNode());
IgniteCache<Object, Object> cache = crd.cache(DEFAULT_CACHE_NAME);
List<Integer> p1Keys = partitionKeys(cache, primaryParts[0], 2, 0);
assertTrue(crd.affinity(DEFAULT_CACHE_NAME).isPrimary(crd.cluster().localNode(), p1Keys.get(0)));
final String primName = crd.name();
cache.put(p1Keys.get(0), 0);
cache.put(p1Keys.get(1), 1);
forceCheckpoint();
List<Ignite> backups = Arrays.asList(grid(1), grid(2));
assertFalse(backups.contains(crd));
final String demanderName = backups.get(0).name();
stopGrid(true, demanderName);
// Create counters delta.
cache.remove(p1Keys.get(1));
stopAllGrids();
crd = startNodeWithBlockingSupplying(0);
startGrid(1);
startNodeWithBlockingSupplying(2);
crd.cluster().active(true);
TestRecordingCommunicationSpi spi0 = TestRecordingCommunicationSpi.spi(crd);
TestRecordingCommunicationSpi spi2 = TestRecordingCommunicationSpi.spi(ignite(2));
IgniteInternalFuture fut = GridTestUtils.runAsync(() -> {
try {
GridTestUtils.waitForCondition(() -> spi0.hasBlockedMessages() || spi2.hasBlockedMessages(), 10_000);
// Stop before supplying rebalance. New rebalance must start with second backup as supplier
// doing full rebalance.
stopGrid(primName);
spi2.stopBlock();
} catch (Exception e) {
fail();
}
});
try {
fut.get(10_000);
} catch (IgniteFutureTimeoutCheckedException e) {
for (Ignite ignite : G.allGrids()) {
final PartitionUpdateCounter cntr = counter(primaryParts[0], ignite.name());
log.info("Node: " + ignite.name() + ", cntr=" + cntr);
}
assertPartitionsSame(idleVerify(crd, DEFAULT_CACHE_NAME));
fail("Rebalancing is expected");
}
awaitPartitionMapExchange();
assertPartitionsSame(idleVerify(grid(demanderName), DEFAULT_CACHE_NAME));
}
use of org.apache.ignite.internal.processors.cache.PartitionUpdateCounter in project ignite by apache.
the class TxPartitionCounterStatePutTest method assertCountersSame.
/**
* @param cacheName Cache name.
*/
private void assertCountersSame(String cacheName) throws AssertionFailedError {
PartitionUpdateCounter c0 = null;
for (Ignite ignite : G.allGrids()) {
PartitionUpdateCounter c = counter(PARTITION_ID, cacheName, ignite.name());
if (c0 == null)
c0 = c;
else {
assertEquals(ignite.name(), c0, c);
c0 = c;
}
}
}
Aggregations