use of org.opensearch.cluster.routing.ShardRouting in project OpenSearch by opensearch-project.
the class IndexShardTests method testRecoverFromCleanStore.
public void testRecoverFromCleanStore() throws IOException {
final IndexShard shard = newStartedShard(true);
indexDoc(shard, "_doc", "0");
if (randomBoolean()) {
flushShard(shard);
}
final ShardRouting shardRouting = shard.routingEntry();
IndexShard newShard = reinitShard(shard, ShardRoutingHelper.initWithSameId(shardRouting, RecoverySource.EmptyStoreRecoverySource.INSTANCE));
DiscoveryNode localNode = new DiscoveryNode("foo", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
newShard.markAsRecovering("store", new RecoveryState(newShard.routingEntry(), localNode, null));
assertTrue(recoverFromStore(newShard));
assertEquals(0, newShard.recoveryState().getTranslog().recoveredOperations());
assertEquals(0, newShard.recoveryState().getTranslog().totalOperations());
assertEquals(0, newShard.recoveryState().getTranslog().totalOperationsOnStart());
assertEquals(100.0f, newShard.recoveryState().getTranslog().recoveredPercent(), 0.01f);
IndexShardTestCase.updateRoutingEntry(newShard, newShard.routingEntry().moveToStarted());
assertDocCount(newShard, 0);
closeShards(newShard);
}
use of org.opensearch.cluster.routing.ShardRouting in project OpenSearch by opensearch-project.
the class IndexShardTests method testFailIfIndexNotPresentInRecoverFromStore.
public void testFailIfIndexNotPresentInRecoverFromStore() throws Exception {
final IndexShard shard = newStartedShard(true);
indexDoc(shard, "_doc", "0");
if (randomBoolean()) {
flushShard(shard);
}
Store store = shard.store();
store.incRef();
closeShards(shard);
cleanLuceneIndex(store.directory());
store.decRef();
IndexShard newShard = reinitShard(shard);
DiscoveryNode localNode = new DiscoveryNode("foo", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
ShardRouting routing = newShard.routingEntry();
newShard.markAsRecovering("store", new RecoveryState(routing, localNode, null));
try {
recoverFromStore(newShard);
fail("index not there!");
} catch (IndexShardRecoveryException ex) {
assertTrue(ex.getMessage().contains("failed to fetch index version after copying it over"));
}
routing = ShardRoutingHelper.moveToUnassigned(routing, new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, "because I say so"));
routing = ShardRoutingHelper.initialize(routing, newShard.routingEntry().currentNodeId());
assertTrue("it's already recovering, we should ignore new ones", newShard.ignoreRecoveryAttempt());
try {
newShard.markAsRecovering("store", new RecoveryState(routing, localNode, null));
fail("we are already recovering, can't mark again");
} catch (IllegalIndexShardStateException e) {
// OK!
}
newShard = reinitShard(newShard, ShardRoutingHelper.initWithSameId(routing, RecoverySource.EmptyStoreRecoverySource.INSTANCE));
newShard.markAsRecovering("store", new RecoveryState(newShard.routingEntry(), localNode, null));
assertTrue("recover even if there is nothing to recover", recoverFromStore(newShard));
IndexShardTestCase.updateRoutingEntry(newShard, newShard.routingEntry().moveToStarted());
assertDocCount(newShard, 0);
// we can't issue this request through a client because of the inconsistencies we created with the cluster state
// doing it directly instead
indexDoc(newShard, "_doc", "0");
newShard.refresh("test");
assertDocCount(newShard, 1);
closeShards(newShard);
}
use of org.opensearch.cluster.routing.ShardRouting in project OpenSearch by opensearch-project.
the class IndexShardTests method testLockingBeforeAndAfterRelocated.
public void testLockingBeforeAndAfterRelocated() throws Exception {
final IndexShard shard = newStartedShard(true);
final ShardRouting routing = ShardRoutingHelper.relocate(shard.routingEntry(), "other_node");
IndexShardTestCase.updateRoutingEntry(shard, routing);
CountDownLatch latch = new CountDownLatch(1);
Thread recoveryThread = new Thread(() -> {
latch.countDown();
try {
shard.relocated(routing.getTargetRelocatingShard().allocationId().getId(), primaryContext -> {
});
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
try (Releasable ignored = acquirePrimaryOperationPermitBlockingly(shard)) {
// start finalization of recovery
recoveryThread.start();
latch.await();
// recovery can only be finalized after we release the current primaryOperationLock
assertFalse(shard.isRelocatedPrimary());
}
// recovery can be now finalized
recoveryThread.join();
assertTrue(shard.isRelocatedPrimary());
final ExecutionException e = expectThrows(ExecutionException.class, () -> acquirePrimaryOperationPermitBlockingly(shard));
assertThat(e.getCause(), instanceOf(ShardNotInPrimaryModeException.class));
assertThat(e.getCause(), hasToString(containsString("shard is not in primary mode")));
closeShards(shard);
}
use of org.opensearch.cluster.routing.ShardRouting in project OpenSearch by opensearch-project.
the class IndexShardTests method testDelayedOperationsBeforeAndAfterRelocated.
public void testDelayedOperationsBeforeAndAfterRelocated() throws Exception {
final IndexShard shard = newStartedShard(true);
final ShardRouting routing = ShardRoutingHelper.relocate(shard.routingEntry(), "other_node");
IndexShardTestCase.updateRoutingEntry(shard, routing);
final CountDownLatch startRecovery = new CountDownLatch(1);
final CountDownLatch relocationStarted = new CountDownLatch(1);
Thread recoveryThread = new Thread(() -> {
try {
startRecovery.await();
shard.relocated(routing.getTargetRelocatingShard().allocationId().getId(), primaryContext -> relocationStarted.countDown());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
recoveryThread.start();
final int numberOfAcquisitions = randomIntBetween(1, 10);
final List<Runnable> assertions = new ArrayList<>(numberOfAcquisitions);
final int recoveryIndex = randomIntBetween(0, numberOfAcquisitions - 1);
for (int i = 0; i < numberOfAcquisitions; i++) {
final PlainActionFuture<Releasable> onLockAcquired;
if (i < recoveryIndex) {
final AtomicBoolean invoked = new AtomicBoolean();
onLockAcquired = new PlainActionFuture<Releasable>() {
@Override
public void onResponse(Releasable releasable) {
invoked.set(true);
releasable.close();
super.onResponse(releasable);
}
@Override
public void onFailure(Exception e) {
throw new AssertionError();
}
};
assertions.add(() -> assertTrue(invoked.get()));
} else if (recoveryIndex == i) {
startRecovery.countDown();
relocationStarted.await();
onLockAcquired = new PlainActionFuture<>();
assertions.add(() -> {
final ExecutionException e = expectThrows(ExecutionException.class, () -> onLockAcquired.get(30, TimeUnit.SECONDS));
assertThat(e.getCause(), instanceOf(ShardNotInPrimaryModeException.class));
assertThat(e.getCause(), hasToString(containsString("shard is not in primary mode")));
});
} else {
onLockAcquired = new PlainActionFuture<>();
assertions.add(() -> {
final ExecutionException e = expectThrows(ExecutionException.class, () -> onLockAcquired.get(30, TimeUnit.SECONDS));
assertThat(e.getCause(), instanceOf(ShardNotInPrimaryModeException.class));
assertThat(e.getCause(), hasToString(containsString("shard is not in primary mode")));
});
}
shard.acquirePrimaryOperationPermit(onLockAcquired, ThreadPool.Names.WRITE, "i_" + i);
}
for (final Runnable assertion : assertions) {
assertion.run();
}
recoveryThread.join();
closeShards(shard);
}
use of org.opensearch.cluster.routing.ShardRouting in project OpenSearch by opensearch-project.
the class IndexShardTests method testPrimaryPromotionDelaysOperations.
public void testPrimaryPromotionDelaysOperations() throws IOException, BrokenBarrierException, InterruptedException {
final IndexShard indexShard = newShard(false);
recoveryEmptyReplica(indexShard, randomBoolean());
final int operations = scaledRandomIntBetween(1, 64);
final CyclicBarrier barrier = new CyclicBarrier(1 + operations);
final CountDownLatch latch = new CountDownLatch(operations);
final CountDownLatch operationLatch = new CountDownLatch(1);
final List<Thread> threads = new ArrayList<>();
for (int i = 0; i < operations; i++) {
final String id = "t_" + i;
final Thread thread = new Thread(() -> {
try {
barrier.await();
} catch (final BrokenBarrierException | InterruptedException e) {
throw new RuntimeException(e);
}
indexShard.acquireReplicaOperationPermit(indexShard.getPendingPrimaryTerm(), indexShard.getLastKnownGlobalCheckpoint(), indexShard.getMaxSeqNoOfUpdatesOrDeletes(), new ActionListener<Releasable>() {
@Override
public void onResponse(Releasable releasable) {
latch.countDown();
try {
operationLatch.await();
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
releasable.close();
}
@Override
public void onFailure(Exception e) {
throw new RuntimeException(e);
}
}, ThreadPool.Names.WRITE, id);
});
thread.start();
threads.add(thread);
}
barrier.await();
latch.await();
final ShardRouting replicaRouting = indexShard.routingEntry();
promoteReplica(indexShard, Collections.singleton(replicaRouting.allocationId().getId()), new IndexShardRoutingTable.Builder(replicaRouting.shardId()).addShard(replicaRouting).build());
final int delayedOperations = scaledRandomIntBetween(1, 64);
final CyclicBarrier delayedOperationsBarrier = new CyclicBarrier(1 + delayedOperations);
final CountDownLatch delayedOperationsLatch = new CountDownLatch(delayedOperations);
final AtomicLong counter = new AtomicLong();
final List<Thread> delayedThreads = new ArrayList<>();
for (int i = 0; i < delayedOperations; i++) {
final String id = "d_" + i;
final Thread thread = new Thread(() -> {
try {
delayedOperationsBarrier.await();
} catch (final BrokenBarrierException | InterruptedException e) {
throw new RuntimeException(e);
}
indexShard.acquirePrimaryOperationPermit(new ActionListener<Releasable>() {
@Override
public void onResponse(Releasable releasable) {
counter.incrementAndGet();
releasable.close();
delayedOperationsLatch.countDown();
}
@Override
public void onFailure(Exception e) {
throw new RuntimeException(e);
}
}, ThreadPool.Names.WRITE, id);
});
thread.start();
delayedThreads.add(thread);
}
delayedOperationsBarrier.await();
assertThat(counter.get(), equalTo(0L));
operationLatch.countDown();
for (final Thread thread : threads) {
thread.join();
}
delayedOperationsLatch.await();
assertThat(counter.get(), equalTo((long) delayedOperations));
for (final Thread thread : delayedThreads) {
thread.join();
}
closeShards(indexShard);
}
Aggregations