Search in sources :

Example 56 with Releasable

use of org.opensearch.common.lease.Releasable 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);
}
Also used : IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) ArrayList(java.util.ArrayList) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) MapperParsingException(org.opensearch.index.mapper.MapperParsingException) IOException(java.io.IOException) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) ExecutionException(java.util.concurrent.ExecutionException) OpenSearchException(org.opensearch.OpenSearchException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) CyclicBarrier(java.util.concurrent.CyclicBarrier) AtomicLong(java.util.concurrent.atomic.AtomicLong) Releasable(org.opensearch.common.lease.Releasable) TestShardRouting.newShardRouting(org.opensearch.cluster.routing.TestShardRouting.newShardRouting) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting)

Example 57 with Releasable

use of org.opensearch.common.lease.Releasable in project OpenSearch by opensearch-project.

the class IndexShardTests method testRestoreLocalHistoryFromTranslogOnPromotion.

public void testRestoreLocalHistoryFromTranslogOnPromotion() throws IOException, InterruptedException {
    final IndexShard indexShard = newStartedShard(false);
    final int operations = 1024 - scaledRandomIntBetween(0, 1024);
    indexOnReplicaWithGaps(indexShard, operations, Math.toIntExact(SequenceNumbers.NO_OPS_PERFORMED));
    final long maxSeqNo = indexShard.seqNoStats().getMaxSeqNo();
    final long globalCheckpointOnReplica = randomLongBetween(UNASSIGNED_SEQ_NO, indexShard.getLocalCheckpoint());
    indexShard.updateGlobalCheckpointOnReplica(globalCheckpointOnReplica, "test");
    final long globalCheckpoint = randomLongBetween(UNASSIGNED_SEQ_NO, indexShard.getLocalCheckpoint());
    final long maxSeqNoOfUpdatesOrDeletesBeforeRollback = indexShard.getMaxSeqNoOfUpdatesOrDeletes();
    final Set<String> docsBeforeRollback = getShardDocUIDs(indexShard);
    final CountDownLatch latch = new CountDownLatch(1);
    randomReplicaOperationPermitAcquisition(indexShard, indexShard.getPendingPrimaryTerm() + 1, globalCheckpoint, randomLongBetween(SequenceNumbers.NO_OPS_PERFORMED, maxSeqNo), new ActionListener<Releasable>() {

        @Override
        public void onResponse(Releasable releasable) {
            releasable.close();
            latch.countDown();
        }

        @Override
        public void onFailure(Exception e) {
        }
    }, "");
    latch.await();
    if (globalCheckpoint < maxSeqNo) {
        assertThat(indexShard.getMaxSeqNoOfUpdatesOrDeletes(), equalTo(maxSeqNo));
    } else {
        assertThat(indexShard.getMaxSeqNoOfUpdatesOrDeletes(), equalTo(maxSeqNoOfUpdatesOrDeletesBeforeRollback));
    }
    final ShardRouting newRouting = indexShard.routingEntry().moveActiveReplicaToPrimary();
    final CountDownLatch resyncLatch = new CountDownLatch(1);
    indexShard.updateShardState(newRouting, indexShard.getPendingPrimaryTerm() + 1, (s, r) -> resyncLatch.countDown(), 1L, Collections.singleton(newRouting.allocationId().getId()), new IndexShardRoutingTable.Builder(newRouting.shardId()).addShard(newRouting).build());
    resyncLatch.await();
    assertThat(indexShard.getLocalCheckpoint(), equalTo(maxSeqNo));
    assertThat(indexShard.seqNoStats().getMaxSeqNo(), equalTo(maxSeqNo));
    assertThat(getShardDocUIDs(indexShard), equalTo(docsBeforeRollback));
    if (globalCheckpoint < maxSeqNo) {
        assertThat(indexShard.getMaxSeqNoOfUpdatesOrDeletes(), equalTo(maxSeqNo));
    } else {
        assertThat(indexShard.getMaxSeqNoOfUpdatesOrDeletes(), equalTo(maxSeqNoOfUpdatesOrDeletesBeforeRollback));
    }
    closeShard(indexShard, false);
}
Also used : IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) MapperParsingException(org.opensearch.index.mapper.MapperParsingException) IOException(java.io.IOException) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) ExecutionException(java.util.concurrent.ExecutionException) OpenSearchException(org.opensearch.OpenSearchException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) Releasable(org.opensearch.common.lease.Releasable) TestShardRouting.newShardRouting(org.opensearch.cluster.routing.TestShardRouting.newShardRouting) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting)

Example 58 with Releasable

use of org.opensearch.common.lease.Releasable 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);
}
Also used : ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) MapperParsingException(org.opensearch.index.mapper.MapperParsingException) IOException(java.io.IOException) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) ExecutionException(java.util.concurrent.ExecutionException) OpenSearchException(org.opensearch.OpenSearchException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) Releasable(org.opensearch.common.lease.Releasable) TestShardRouting.newShardRouting(org.opensearch.cluster.routing.TestShardRouting.newShardRouting) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) ExecutionException(java.util.concurrent.ExecutionException)

Example 59 with Releasable

use of org.opensearch.common.lease.Releasable in project OpenSearch by opensearch-project.

the class TranslogDeletionPolicyTests method testRetentionHierarchy.

/**
 * Tests that age trumps size but recovery trumps both.
 */
public void testRetentionHierarchy() throws IOException {
    long now = System.currentTimeMillis();
    Tuple<List<TranslogReader>, TranslogWriter> readersAndWriter = createReadersAndWriter(now);
    List<BaseTranslogReader> allGens = new ArrayList<>(readersAndWriter.v1());
    allGens.add(readersAndWriter.v2());
    try {
        DefaultTranslogDeletionPolicy deletionPolicy = new MockDeletionPolicy(now, Long.MAX_VALUE, Long.MAX_VALUE, Integer.MAX_VALUE);
        int selectedReader = randomIntBetween(0, allGens.size() - 1);
        final long selectedGenerationByAge = allGens.get(selectedReader).generation;
        long maxAge = now - allGens.get(selectedReader).getLastModifiedTime();
        selectedReader = randomIntBetween(0, allGens.size() - 1);
        final long selectedGenerationBySize = allGens.get(selectedReader).generation;
        long size = allGens.stream().skip(selectedReader).map(BaseTranslogReader::sizeInBytes).reduce(Long::sum).get();
        selectedReader = randomIntBetween(0, allGens.size() - 1);
        final long selectedGenerationByTotalFiles = allGens.get(selectedReader).generation;
        deletionPolicy.setRetentionAgeInMillis(maxAge);
        deletionPolicy.setRetentionSizeInBytes(size);
        final int totalFiles = allGens.size() - selectedReader;
        deletionPolicy.setRetentionTotalFiles(totalFiles);
        assertMinGenRequired(deletionPolicy, readersAndWriter, max3(selectedGenerationByAge, selectedGenerationBySize, selectedGenerationByTotalFiles));
        // make a new policy as committed gen can't go backwards (for now)
        deletionPolicy = new MockDeletionPolicy(now, size, maxAge, totalFiles);
        assertMinGenRequired(deletionPolicy, readersAndWriter, max3(selectedGenerationByAge, selectedGenerationBySize, selectedGenerationByTotalFiles));
        long viewGen = randomFrom(allGens).generation;
        try (Releasable ignored = deletionPolicy.acquireTranslogGen(viewGen)) {
            assertMinGenRequired(deletionPolicy, readersAndWriter, min(viewGen, max3(selectedGenerationByAge, selectedGenerationBySize, selectedGenerationByTotalFiles)));
            // disable age
            deletionPolicy.setRetentionAgeInMillis(-1);
            assertMinGenRequired(deletionPolicy, readersAndWriter, min(viewGen, Math.max(selectedGenerationBySize, selectedGenerationByTotalFiles)));
            // disable size
            deletionPolicy.setRetentionAgeInMillis(maxAge);
            deletionPolicy.setRetentionSizeInBytes(-1);
            assertMinGenRequired(deletionPolicy, readersAndWriter, min(viewGen, Math.max(selectedGenerationByAge, selectedGenerationByTotalFiles)));
            // disable age and zie
            deletionPolicy.setRetentionAgeInMillis(-1);
            deletionPolicy.setRetentionSizeInBytes(-1);
            assertMinGenRequired(deletionPolicy, readersAndWriter, viewGen);
            // disable total files
            deletionPolicy.setRetentionTotalFiles(0);
            assertMinGenRequired(deletionPolicy, readersAndWriter, viewGen);
        }
    } finally {
        IOUtils.close(readersAndWriter.v1());
        IOUtils.close(readersAndWriter.v2());
    }
}
Also used : ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) Releasable(org.opensearch.common.lease.Releasable)

Example 60 with Releasable

use of org.opensearch.common.lease.Releasable in project OpenSearch by opensearch-project.

the class TransportWriteActionTests method mockIndexShard.

private IndexShard mockIndexShard(ShardId shardId, ClusterService clusterService) {
    final IndexShard indexShard = mock(IndexShard.class);
    doAnswer(invocation -> {
        ActionListener<Releasable> callback = (ActionListener<Releasable>) invocation.getArguments()[0];
        count.incrementAndGet();
        callback.onResponse(count::decrementAndGet);
        return null;
    }).when(indexShard).acquirePrimaryOperationPermit(any(ActionListener.class), anyString(), any());
    doAnswer(invocation -> {
        long term = (Long) invocation.getArguments()[0];
        ActionListener<Releasable> callback = (ActionListener<Releasable>) invocation.getArguments()[1];
        final long primaryTerm = indexShard.getPendingPrimaryTerm();
        if (term < primaryTerm) {
            throw new IllegalArgumentException(String.format(Locale.ROOT, "%s operation term [%d] is too old (current [%d])", shardId, term, primaryTerm));
        }
        count.incrementAndGet();
        callback.onResponse(count::decrementAndGet);
        return null;
    }).when(indexShard).acquireReplicaOperationPermit(anyLong(), anyLong(), anyLong(), any(ActionListener.class), anyString(), any());
    when(indexShard.routingEntry()).thenAnswer(invocationOnMock -> {
        final ClusterState state = clusterService.state();
        final RoutingNode node = state.getRoutingNodes().node(state.nodes().getLocalNodeId());
        final ShardRouting routing = node.getByShardId(shardId);
        if (routing == null) {
            throw new ShardNotFoundException(shardId, "shard is no longer assigned to current node");
        }
        return routing;
    });
    when(indexShard.isRelocatedPrimary()).thenAnswer(invocationOnMock -> isRelocated.get());
    doThrow(new AssertionError("failed shard is not supported")).when(indexShard).failShard(anyString(), any(Exception.class));
    when(indexShard.getPendingPrimaryTerm()).thenAnswer(i -> clusterService.state().metadata().getIndexSafe(shardId.getIndex()).primaryTerm(shardId.id()));
    return indexShard;
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) IndexShard(org.opensearch.index.shard.IndexShard) OpenSearchException(org.opensearch.OpenSearchException) NoNodeAvailableException(org.opensearch.client.transport.NoNodeAvailableException) NodeClosedException(org.opensearch.node.NodeClosedException) TransportException(org.opensearch.transport.TransportException) IOException(java.io.IOException) ShardNotFoundException(org.opensearch.index.shard.ShardNotFoundException) ExecutionException(java.util.concurrent.ExecutionException) ActionListener(org.opensearch.action.ActionListener) RoutingNode(org.opensearch.cluster.routing.RoutingNode) ShardNotFoundException(org.opensearch.index.shard.ShardNotFoundException) Mockito.anyLong(org.mockito.Mockito.anyLong) Releasable(org.opensearch.common.lease.Releasable) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting)

Aggregations

Releasable (org.opensearch.common.lease.Releasable)161 ShardId (org.opensearch.index.shard.ShardId)50 IOException (java.io.IOException)45 CountDownLatch (java.util.concurrent.CountDownLatch)36 Settings (org.opensearch.common.settings.Settings)35 IndexingPressurePerShardStats (org.opensearch.index.stats.IndexingPressurePerShardStats)32 ExecutionException (java.util.concurrent.ExecutionException)30 ArrayList (java.util.ArrayList)28 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)28 AlreadyClosedException (org.apache.lucene.store.AlreadyClosedException)27 OpenSearchException (org.opensearch.OpenSearchException)25 ThreadPool (org.opensearch.threadpool.ThreadPool)25 PlainActionFuture (org.opensearch.action.support.PlainActionFuture)24 ActionListener (org.opensearch.action.ActionListener)23 IndexRequest (org.opensearch.action.index.IndexRequest)22 ShardRouting (org.opensearch.cluster.routing.ShardRouting)22 IndexingPressureStats (org.opensearch.index.stats.IndexingPressureStats)22 BrokenBarrierException (java.util.concurrent.BrokenBarrierException)21 List (java.util.List)20 Translog (org.opensearch.index.translog.Translog)19