Search in sources :

Example 21 with RetentionLeases

use of org.opensearch.index.seqno.RetentionLeases in project OpenSearch by opensearch-project.

the class IndexShardTests method testShardActiveDuringPeerRecovery.

public void testShardActiveDuringPeerRecovery() throws IOException {
    Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1).put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).build();
    IndexMetadata metadata = IndexMetadata.builder("test").putMapping("{ \"properties\": { \"foo\":  { \"type\": \"text\"}}}").settings(settings).primaryTerm(0, 1).build();
    IndexShard primary = newShard(new ShardId(metadata.getIndex(), 0), true, "n1", metadata, null);
    recoverShardFromStore(primary);
    indexDoc(primary, "_doc", "0", "{\"foo\" : \"bar\"}");
    IndexShard replica = newShard(primary.shardId(), false, "n2", metadata, null);
    DiscoveryNode localNode = new DiscoveryNode("foo", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
    replica.markAsRecovering("for testing", new RecoveryState(replica.routingEntry(), localNode, localNode));
    // Shard is still inactive since we haven't started recovering yet
    assertFalse(replica.isActive());
    recoverReplica(replica, primary, (shard, discoveryNode) -> new RecoveryTarget(shard, discoveryNode, recoveryListener) {

        @Override
        public void indexTranslogOperations(final List<Translog.Operation> operations, final int totalTranslogOps, final long maxAutoIdTimestamp, final long maxSeqNoOfUpdatesOrDeletes, final RetentionLeases retentionLeases, final long mappingVersion, final ActionListener<Long> listener) {
            super.indexTranslogOperations(operations, totalTranslogOps, maxAutoIdTimestamp, maxSeqNoOfUpdatesOrDeletes, retentionLeases, mappingVersion, ActionListener.wrap(checkpoint -> {
                listener.onResponse(checkpoint);
                // Shard should now be active since we did recover:
                assertTrue(replica.isActive());
            }, listener::onFailure));
        }
    }, false, true);
    closeShards(primary, replica);
}
Also used : DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) RecoveryTarget(org.opensearch.indices.recovery.RecoveryTarget) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) AtomicLong(java.util.concurrent.atomic.AtomicLong) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) RecoveryState(org.opensearch.indices.recovery.RecoveryState) IndexScopedSettings(org.opensearch.common.settings.IndexScopedSettings) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings)

Example 22 with RetentionLeases

use of org.opensearch.index.seqno.RetentionLeases in project OpenSearch by opensearch-project.

the class IndexShardTests method testRefreshListenersDuringPeerRecovery.

public void testRefreshListenersDuringPeerRecovery() throws IOException {
    Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1).put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).build();
    IndexMetadata metadata = IndexMetadata.builder("test").putMapping("{ \"properties\": { \"foo\":  { \"type\": \"text\"}}}").settings(settings).primaryTerm(0, 1).build();
    IndexShard primary = newShard(new ShardId(metadata.getIndex(), 0), true, "n1", metadata, null);
    recoverShardFromStore(primary);
    indexDoc(primary, "_doc", "0", "{\"foo\" : \"bar\"}");
    Consumer<IndexShard> assertListenerCalled = shard -> {
        AtomicBoolean called = new AtomicBoolean();
        shard.addRefreshListener(null, b -> {
            assertFalse(b);
            called.set(true);
        });
        assertTrue(called.get());
    };
    IndexShard replica = newShard(primary.shardId(), false, "n2", metadata, null);
    DiscoveryNode localNode = new DiscoveryNode("foo", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
    replica.markAsRecovering("for testing", new RecoveryState(replica.routingEntry(), localNode, localNode));
    assertListenerCalled.accept(replica);
    recoverReplica(replica, primary, (shard, discoveryNode) -> new RecoveryTarget(shard, discoveryNode, recoveryListener) {

        // we're only checking that listeners are called when the engine is open, before there is no point
        @Override
        public void prepareForTranslogOperations(int totalTranslogOps, ActionListener<Void> listener) {
            super.prepareForTranslogOperations(totalTranslogOps, ActionListener.wrap(r -> {
                assertListenerCalled.accept(replica);
                listener.onResponse(r);
            }, listener::onFailure));
        }

        @Override
        public void indexTranslogOperations(final List<Translog.Operation> operations, final int totalTranslogOps, final long maxAutoIdTimestamp, final long maxSeqNoOfUpdatesOrDeletes, final RetentionLeases retentionLeases, final long mappingVersion, final ActionListener<Long> listener) {
            super.indexTranslogOperations(operations, totalTranslogOps, maxAutoIdTimestamp, maxSeqNoOfUpdatesOrDeletes, retentionLeases, mappingVersion, ActionListener.wrap(r -> {
                assertListenerCalled.accept(replica);
                listener.onResponse(r);
            }, listener::onFailure));
        }

        @Override
        public void finalizeRecovery(long globalCheckpoint, long trimAboveSeqNo, ActionListener<Void> listener) {
            super.finalizeRecovery(globalCheckpoint, trimAboveSeqNo, ActionListener.wrap(r -> {
                assertListenerCalled.accept(replica);
                listener.onResponse(r);
            }, listener::onFailure));
        }
    }, false, true);
    closeShards(primary, replica);
}
Also used : Matchers.hasToString(org.hamcrest.Matchers.hasToString) SeqNoStats(org.opensearch.index.seqno.SeqNoStats) SequenceNumbers(org.opensearch.index.seqno.SequenceNumbers) MockFSDirectoryFactory(org.opensearch.test.store.MockFSDirectoryFactory) Arrays(java.util.Arrays) NRTReplicationEngineFactory(org.opensearch.index.engine.NRTReplicationEngineFactory) CheckedFunction(org.opensearch.common.CheckedFunction) IndexScopedSettings(org.opensearch.common.settings.IndexScopedSettings) Term(org.apache.lucene.index.Term) Matchers.not(org.hamcrest.Matchers.not) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) Version(org.opensearch.Version) ReferenceManager(org.apache.lucene.search.ReferenceManager) Strings(org.opensearch.common.Strings) InternalEngine(org.opensearch.index.engine.InternalEngine) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) IndexFieldDataCache(org.opensearch.index.fielddata.IndexFieldDataCache) RecoveryState(org.opensearch.indices.recovery.RecoveryState) Map(java.util.Map) Matchers.nullValue(org.hamcrest.Matchers.nullValue) ActionListener(org.opensearch.action.ActionListener) IOContext(org.apache.lucene.store.IOContext) Path(java.nio.file.Path) NodeEnvironment(org.opensearch.env.NodeEnvironment) TimeValue(org.opensearch.common.unit.TimeValue) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) ReplicationTracker(org.opensearch.index.seqno.ReplicationTracker) RegexMatcher.matches(org.opensearch.test.hamcrest.RegexMatcher.matches) Engine(org.opensearch.index.engine.Engine) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) FieldMaskingReader(org.opensearch.test.FieldMaskingReader) FileVisitResult(java.nio.file.FileVisitResult) CountDownLatch(java.util.concurrent.CountDownLatch) Logger(org.apache.logging.log4j.Logger) EngineConfigFactory(org.opensearch.index.engine.EngineConfigFactory) Stream(java.util.stream.Stream) Randomness(org.opensearch.common.Randomness) BytesArray(org.opensearch.common.bytes.BytesArray) XContentType(org.opensearch.common.xcontent.XContentType) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) Matchers.containsString(org.hamcrest.Matchers.containsString) Matchers.in(org.hamcrest.Matchers.in) Mockito.mock(org.mockito.Mockito.mock) IndexCommit(org.apache.lucene.index.IndexCommit) XContentFactory.jsonBuilder(org.opensearch.common.xcontent.XContentFactory.jsonBuilder) CodecService(org.opensearch.index.codec.CodecService) FlushRequest(org.opensearch.action.admin.indices.flush.FlushRequest) MapperParsingException(org.opensearch.index.mapper.MapperParsingException) ThreadPool(org.opensearch.threadpool.ThreadPool) TestShardRouting.newShardRouting(org.opensearch.cluster.routing.TestShardRouting.newShardRouting) Releasable(org.opensearch.common.lease.Releasable) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) RecoverySource(org.opensearch.cluster.routing.RecoverySource) DocIdSeqNoAndSource(org.opensearch.index.engine.DocIdSeqNoAndSource) UNASSIGNED_SEQ_NO(org.opensearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO) VersionUtils(org.opensearch.test.VersionUtils) ShardRoutingState(org.opensearch.cluster.routing.ShardRoutingState) VersionFieldMapper(org.opensearch.index.mapper.VersionFieldMapper) Matchers.hasSize(org.hamcrest.Matchers.hasSize) ParsedDocument(org.opensearch.index.mapper.ParsedDocument) CorruptionUtils(org.opensearch.test.CorruptionUtils) CommitStats(org.opensearch.index.engine.CommitStats) TopDocs(org.apache.lucene.search.TopDocs) ParseContext(org.opensearch.index.mapper.ParseContext) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) Files(java.nio.file.Files) TestTranslog(org.opensearch.index.translog.TestTranslog) IOException(java.io.IOException) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) BytesStreamOutput(org.opensearch.common.io.stream.BytesStreamOutput) SourceFieldMapper(org.opensearch.index.mapper.SourceFieldMapper) IndexFieldDataService(org.opensearch.index.fielddata.IndexFieldDataService) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) Matchers.sameInstance(org.hamcrest.Matchers.sameInstance) NamedXContentRegistry(org.opensearch.common.xcontent.NamedXContentRegistry) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) ShardStats(org.opensearch.action.admin.indices.stats.ShardStats) Assert(org.junit.Assert) RetentionLeaseSyncer(org.opensearch.index.seqno.RetentionLeaseSyncer) SeqNoFieldMapper(org.opensearch.index.mapper.SeqNoFieldMapper) CommonStats(org.opensearch.action.admin.indices.stats.CommonStats) ReadOnlyEngine(org.opensearch.index.engine.ReadOnlyEngine) IdFieldMapper(org.opensearch.index.mapper.IdFieldMapper) Matchers.either(org.hamcrest.Matchers.either) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) FieldDataStats(org.opensearch.index.fielddata.FieldDataStats) IndexableField(org.apache.lucene.index.IndexableField) Lucene.cleanLuceneIndex(org.opensearch.common.lucene.Lucene.cleanLuceneIndex) NoneCircuitBreakerService(org.opensearch.indices.breaker.NoneCircuitBreakerService) OpenSearchException(org.opensearch.OpenSearchException) Releasables(org.opensearch.common.lease.Releasables) CommonStatsFlags(org.opensearch.action.admin.indices.stats.CommonStatsFlags) Matchers.hasKey(org.hamcrest.Matchers.hasKey) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) ForceMergeRequest(org.opensearch.action.admin.indices.forcemerge.ForceMergeRequest) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) MapperService(org.opensearch.index.mapper.MapperService) IndexId(org.opensearch.repositories.IndexId) Matchers.everyItem(org.hamcrest.Matchers.everyItem) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Locale(java.util.Locale) Directory(org.apache.lucene.store.Directory) Assertions(org.opensearch.Assertions) XContentFactory(org.opensearch.common.xcontent.XContentFactory) DummyShardLock(org.opensearch.test.DummyShardLock) ReplicationLuceneIndex(org.opensearch.indices.replication.common.ReplicationLuceneIndex) UnassignedInfo(org.opensearch.cluster.routing.UnassignedInfo) SegmentReplicationCheckpointPublisher(org.opensearch.indices.replication.checkpoint.SegmentReplicationCheckpointPublisher) SimpleFileVisitor(java.nio.file.SimpleFileVisitor) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) EngineTestCase(org.opensearch.index.engine.EngineTestCase) CyclicBarrier(java.util.concurrent.CyclicBarrier) BytesRef(org.apache.lucene.util.BytesRef) MappedFieldType(org.opensearch.index.mapper.MappedFieldType) SnapshotId(org.opensearch.snapshots.SnapshotId) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) DirectoryReader(org.apache.lucene.index.DirectoryReader) Store(org.opensearch.index.store.Store) Collectors(java.util.stream.Collectors) Tuple(org.opensearch.common.collect.Tuple) GatedCloseable(org.opensearch.common.concurrent.GatedCloseable) List(java.util.List) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) Matchers.equalTo(org.hamcrest.Matchers.equalTo) IndexSettings(org.opensearch.index.IndexSettings) ShardRoutingHelper(org.opensearch.cluster.routing.ShardRoutingHelper) Uid(org.opensearch.index.mapper.Uid) TranslogStats(org.opensearch.index.translog.TranslogStats) MappingMetadata(org.opensearch.cluster.metadata.MappingMetadata) IntStream(java.util.stream.IntStream) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EngineConfig(org.opensearch.index.engine.EngineConfig) StoreUtils(org.opensearch.index.store.StoreUtils) IndicesFieldDataCache(org.opensearch.indices.fielddata.cache.IndicesFieldDataCache) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) HashSet(java.util.HashSet) IndexFieldData(org.opensearch.index.fielddata.IndexFieldData) SourceToParse(org.opensearch.index.mapper.SourceToParse) Charset(java.nio.charset.Charset) Translog(org.opensearch.index.translog.Translog) UUIDs(org.opensearch.common.UUIDs) IndicesQueryCache(org.opensearch.indices.IndicesQueryCache) StoreStats(org.opensearch.index.store.StoreStats) RetentionLease(org.opensearch.index.seqno.RetentionLease) StreamInput(org.opensearch.common.io.stream.StreamInput) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) Collections.emptyMap(java.util.Collections.emptyMap) Matchers.oneOf(org.hamcrest.Matchers.oneOf) NRTReplicationEngine(org.opensearch.index.engine.NRTReplicationEngine) RecoveryTarget(org.opensearch.indices.recovery.RecoveryTarget) LongFunction(java.util.function.LongFunction) Collections.emptySet(java.util.Collections.emptySet) AllocationId(org.opensearch.cluster.routing.AllocationId) Semaphore(java.util.concurrent.Semaphore) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) EMPTY_PARAMS(org.opensearch.common.xcontent.ToXContent.EMPTY_PARAMS) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) TermQuery(org.apache.lucene.search.TermQuery) Constants(org.apache.lucene.util.Constants) AtomicArray(org.opensearch.common.util.concurrent.AtomicArray) FilterDirectory(org.apache.lucene.store.FilterDirectory) Snapshot(org.opensearch.snapshots.Snapshot) ReplicationType(org.opensearch.indices.replication.common.ReplicationType) IndexRequest(org.opensearch.action.index.IndexRequest) Collections(java.util.Collections) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) RecoveryTarget(org.opensearch.indices.recovery.RecoveryTarget) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) RecoveryState(org.opensearch.indices.recovery.RecoveryState) IndexScopedSettings(org.opensearch.common.settings.IndexScopedSettings) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings)

Example 23 with RetentionLeases

use of org.opensearch.index.seqno.RetentionLeases in project OpenSearch by opensearch-project.

the class RecoveryDuringReplicationTests method testCheckpointsAndMarkingInSync.

public void testCheckpointsAndMarkingInSync() throws Exception {
    final IndexMetadata metadata = buildIndexMetadata(0);
    final BlockingEngineFactory replicaEngineFactory = new BlockingEngineFactory();
    try (ReplicationGroup shards = new ReplicationGroup(metadata) {

        @Override
        protected EngineFactory getEngineFactory(final ShardRouting routing) {
            if (routing.primary()) {
                return new InternalEngineFactory();
            } else {
                return replicaEngineFactory;
            }
        }
    };
        // make sure we release indexers before closing
        AutoCloseable ignored = replicaEngineFactory) {
        shards.startPrimary();
        final int docs = shards.indexDocs(randomIntBetween(1, 10));
        logger.info("indexed [{}] docs", docs);
        final CountDownLatch pendingDocDone = new CountDownLatch(1);
        final CountDownLatch pendingDocActiveWithExtraDocIndexed = new CountDownLatch(1);
        final CountDownLatch phaseTwoStartLatch = new CountDownLatch(1);
        final IndexShard replica = shards.addReplica();
        final Future<Void> recoveryFuture = shards.asyncRecoverReplica(replica, (indexShard, node) -> new RecoveryTarget(indexShard, node, recoveryListener) {

            @Override
            public void indexTranslogOperations(final List<Translog.Operation> operations, final int totalTranslogOps, final long maxAutoIdTimestamp, final long maxSeqNoOfUpdates, final RetentionLeases retentionLeases, final long mappingVersion, final ActionListener<Long> listener) {
                // index a doc which is not part of the snapshot, but also does not complete on replica
                replicaEngineFactory.latchIndexers(1);
                threadPool.generic().submit(() -> {
                    try {
                        shards.index(new IndexRequest(index.getName()).id("pending").source("{}", XContentType.JSON));
                    } catch (final Exception e) {
                        throw new RuntimeException(e);
                    } finally {
                        pendingDocDone.countDown();
                    }
                });
                try {
                    // the pending doc is latched in the engine
                    replicaEngineFactory.awaitIndexersLatch();
                    // unblock indexing for the next doc
                    replicaEngineFactory.allowIndexing();
                    shards.index(new IndexRequest(index.getName()).id("completed").source("{}", XContentType.JSON));
                    pendingDocActiveWithExtraDocIndexed.countDown();
                } catch (final Exception e) {
                    throw new AssertionError(e);
                }
                try {
                    phaseTwoStartLatch.await();
                } catch (InterruptedException e) {
                    throw new AssertionError(e);
                }
                super.indexTranslogOperations(operations, totalTranslogOps, maxAutoIdTimestamp, maxSeqNoOfUpdates, retentionLeases, mappingVersion, listener);
            }
        });
        pendingDocActiveWithExtraDocIndexed.await();
        assertThat(pendingDocDone.getCount(), equalTo(1L));
        {
            final long expectedDocs = docs + 2L;
            assertThat(shards.getPrimary().getLocalCheckpoint(), equalTo(expectedDocs - 1));
            // recovery has not completed, therefore the global checkpoint can have advanced on the primary
            assertThat(shards.getPrimary().getLastKnownGlobalCheckpoint(), equalTo(expectedDocs - 1));
            // the pending document is not done, the checkpoints can not have advanced on the replica
            assertThat(replica.getLocalCheckpoint(), lessThan(expectedDocs - 1));
            assertThat(replica.getLastKnownGlobalCheckpoint(), lessThan(expectedDocs - 1));
        }
        // wait for recovery to enter the translog phase
        phaseTwoStartLatch.countDown();
        // wait for the translog phase to complete and the recovery to block global checkpoint advancement
        assertBusy(() -> assertTrue(shards.getPrimary().pendingInSync()));
        {
            shards.index(new IndexRequest(index.getName()).id("last").source("{}", XContentType.JSON));
            final long expectedDocs = docs + 3L;
            assertThat(shards.getPrimary().getLocalCheckpoint(), equalTo(expectedDocs - 1));
            // recovery is now in the process of being completed, therefore the global checkpoint can not have advanced on the primary
            assertThat(shards.getPrimary().getLastKnownGlobalCheckpoint(), equalTo(expectedDocs - 2));
            assertThat(replica.getLocalCheckpoint(), lessThan(expectedDocs - 2));
            assertThat(replica.getLastKnownGlobalCheckpoint(), lessThan(expectedDocs - 2));
        }
        replicaEngineFactory.releaseLatchedIndexers();
        pendingDocDone.await();
        recoveryFuture.get();
        {
            final long expectedDocs = docs + 3L;
            assertBusy(() -> {
                assertThat(shards.getPrimary().getLocalCheckpoint(), equalTo(expectedDocs - 1));
                assertThat(shards.getPrimary().getLastKnownGlobalCheckpoint(), equalTo(expectedDocs - 1));
                assertThat(replica.getLocalCheckpoint(), equalTo(expectedDocs - 1));
                // the global checkpoint advances can only advance here if a background global checkpoint sync fires
                assertThat(replica.getLastKnownGlobalCheckpoint(), anyOf(equalTo(expectedDocs - 1), equalTo(expectedDocs - 2)));
            });
        }
    }
}
Also used : IndexShard(org.opensearch.index.shard.IndexShard) RecoveryTarget(org.opensearch.indices.recovery.RecoveryTarget) CountDownLatch(java.util.concurrent.CountDownLatch) IndexRequest(org.opensearch.action.index.IndexRequest) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) IOException(java.io.IOException) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ShardRouting(org.opensearch.cluster.routing.ShardRouting)

Example 24 with RetentionLeases

use of org.opensearch.index.seqno.RetentionLeases in project OpenSearch by opensearch-project.

the class RetentionLeasesReplicationTests method testSimpleSyncRetentionLeases.

public void testSimpleSyncRetentionLeases() throws Exception {
    Settings settings = Settings.builder().put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true).build();
    try (ReplicationGroup group = createGroup(between(0, 2), settings)) {
        group.startAll();
        List<RetentionLease> leases = new ArrayList<>();
        int iterations = between(1, 100);
        CountDownLatch latch = new CountDownLatch(iterations);
        for (int i = 0; i < iterations; i++) {
            if (leases.isEmpty() == false && rarely()) {
                RetentionLease leaseToRemove = randomFrom(leases);
                leases.remove(leaseToRemove);
                group.removeRetentionLease(leaseToRemove.id(), ActionListener.wrap(latch::countDown));
            } else {
                RetentionLease newLease = group.addRetentionLease(Integer.toString(i), randomNonNegativeLong(), "test-" + i, ActionListener.wrap(latch::countDown));
                leases.add(newLease);
            }
        }
        RetentionLeases leasesOnPrimary = group.getPrimary().getRetentionLeases();
        assertThat(leasesOnPrimary.version(), equalTo(iterations + group.getReplicas().size() + 1L));
        assertThat(leasesOnPrimary.primaryTerm(), equalTo(group.getPrimary().getOperationPrimaryTerm()));
        assertThat(RetentionLeaseUtils.toMapExcludingPeerRecoveryRetentionLeases(leasesOnPrimary).values(), containsInAnyOrder(leases.toArray(new RetentionLease[0])));
        latch.await();
        for (IndexShard replica : group.getReplicas()) {
            assertThat(replica.getRetentionLeases(), equalTo(leasesOnPrimary));
        }
    }
}
Also used : RetentionLease(org.opensearch.index.seqno.RetentionLease) IndexShard(org.opensearch.index.shard.IndexShard) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings) RetentionLeases(org.opensearch.index.seqno.RetentionLeases)

Example 25 with RetentionLeases

use of org.opensearch.index.seqno.RetentionLeases in project OpenSearch by opensearch-project.

the class RetentionLeasesReplicationTests method testSyncRetentionLeasesWithPrimaryPromotion.

public void testSyncRetentionLeasesWithPrimaryPromotion() throws Exception {
    Settings settings = Settings.builder().put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true).build();
    int numberOfReplicas = between(2, 4);
    IndexMetadata indexMetadata = buildIndexMetadata(numberOfReplicas, settings, indexMapping);
    try (ReplicationGroup group = new ReplicationGroup(indexMetadata) {

        @Override
        protected void syncRetentionLeases(ShardId shardId, RetentionLeases leases, ActionListener<ReplicationResponse> listener) {
            listener.onResponse(new SyncRetentionLeasesResponse(new RetentionLeaseSyncAction.Request(shardId, leases)));
        }
    }) {
        group.startAll();
        for (IndexShard replica : group.getReplicas()) {
            replica.updateRetentionLeasesOnReplica(group.getPrimary().getRetentionLeases());
        }
        int numLeases = between(1, 100);
        IndexShard newPrimary = randomFrom(group.getReplicas());
        RetentionLeases latestRetentionLeasesOnNewPrimary = newPrimary.getRetentionLeases();
        for (int i = 0; i < numLeases; i++) {
            PlainActionFuture<ReplicationResponse> addLeaseFuture = new PlainActionFuture<>();
            group.addRetentionLease(Integer.toString(i), randomNonNegativeLong(), "test-" + i, addLeaseFuture);
            RetentionLeaseSyncAction.Request request = ((SyncRetentionLeasesResponse) addLeaseFuture.actionGet()).syncRequest;
            for (IndexShard replica : randomSubsetOf(group.getReplicas())) {
                group.executeRetentionLeasesSyncRequestOnReplica(request, replica);
                if (newPrimary == replica) {
                    latestRetentionLeasesOnNewPrimary = request.getRetentionLeases();
                }
            }
        }
        group.promoteReplicaToPrimary(newPrimary).get();
        // we need to make changes to retention leases to sync it to replicas
        // since we don't sync retention leases when promoting a new primary.
        PlainActionFuture<ReplicationResponse> newLeaseFuture = new PlainActionFuture<>();
        group.addRetentionLease("new-lease-after-promotion", randomNonNegativeLong(), "test", newLeaseFuture);
        RetentionLeases leasesOnPrimary = group.getPrimary().getRetentionLeases();
        assertThat(leasesOnPrimary.primaryTerm(), equalTo(group.getPrimary().getOperationPrimaryTerm()));
        assertThat(leasesOnPrimary.version(), equalTo(latestRetentionLeasesOnNewPrimary.version() + 1));
        assertThat(leasesOnPrimary.leases(), hasSize(latestRetentionLeasesOnNewPrimary.leases().size() + 1));
        RetentionLeaseSyncAction.Request request = ((SyncRetentionLeasesResponse) newLeaseFuture.actionGet()).syncRequest;
        for (IndexShard replica : group.getReplicas()) {
            group.executeRetentionLeasesSyncRequestOnReplica(request, replica);
        }
        for (IndexShard replica : group.getReplicas()) {
            assertThat(replica.getRetentionLeases(), equalTo(leasesOnPrimary));
        }
    }
}
Also used : IndexShard(org.opensearch.index.shard.IndexShard) RetentionLeaseSyncAction(org.opensearch.index.seqno.RetentionLeaseSyncAction) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) ReplicationResponse(org.opensearch.action.support.replication.ReplicationResponse) ShardId(org.opensearch.index.shard.ShardId) ActionListener(org.opensearch.action.ActionListener) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings)

Aggregations

RetentionLeases (org.opensearch.index.seqno.RetentionLeases)31 ArrayList (java.util.ArrayList)16 IndexSettings (org.opensearch.index.IndexSettings)16 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)14 AtomicLong (java.util.concurrent.atomic.AtomicLong)13 Settings (org.opensearch.common.settings.Settings)13 PlainActionFuture (org.opensearch.action.support.PlainActionFuture)12 RetentionLease (org.opensearch.index.seqno.RetentionLease)12 IndexShard (org.opensearch.index.shard.IndexShard)12 List (java.util.List)11 ActionListener (org.opensearch.action.ActionListener)11 IOException (java.io.IOException)10 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)10 CountDownLatch (java.util.concurrent.CountDownLatch)9 IndexCommit (org.apache.lucene.index.IndexCommit)9 ShardRouting (org.opensearch.cluster.routing.ShardRouting)9 GatedCloseable (org.opensearch.common.concurrent.GatedCloseable)8 ReplicationTracker (org.opensearch.index.seqno.ReplicationTracker)8 Translog (org.opensearch.index.translog.Translog)8 Arrays (java.util.Arrays)7