Search in sources :

Example 6 with RetentionLeases

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

the class RecoverySourceHandler method recoverToTarget.

/**
 * performs the recovery from the local engine to the target
 */
public void recoverToTarget(ActionListener<RecoveryResponse> listener) {
    addListener(listener);
    final Closeable releaseResources = () -> IOUtils.close(resources);
    try {
        cancellableThreads.setOnCancel((reason, beforeCancelEx) -> {
            final RuntimeException e;
            if (shard.state() == IndexShardState.CLOSED) {
                // check if the shard got closed on us
                e = new IndexShardClosedException(shard.shardId(), "shard is closed and recovery was canceled reason [" + reason + "]");
            } else {
                e = new CancellableThreads.ExecutionCancelledException("recovery was canceled reason [" + reason + "]");
            }
            if (beforeCancelEx != null) {
                e.addSuppressed(beforeCancelEx);
            }
            IOUtils.closeWhileHandlingException(releaseResources, () -> future.onFailure(e));
            throw e;
        });
        final Consumer<Exception> onFailure = e -> {
            assert Transports.assertNotTransportThread(RecoverySourceHandler.this + "[onFailure]");
            IOUtils.closeWhileHandlingException(releaseResources, () -> future.onFailure(e));
        };
        final SetOnce<RetentionLease> retentionLeaseRef = new SetOnce<>();
        runUnderPrimaryPermit(() -> {
            final IndexShardRoutingTable routingTable = shard.getReplicationGroup().getRoutingTable();
            ShardRouting targetShardRouting = routingTable.getByAllocationId(request.targetAllocationId());
            if (targetShardRouting == null) {
                logger.debug("delaying recovery of {} as it is not listed as assigned to target node {}", request.shardId(), request.targetNode());
                throw new DelayRecoveryException("source node does not have the shard listed in its state as allocated on the node");
            }
            assert targetShardRouting.initializing() : "expected recovery target to be initializing but was " + targetShardRouting;
            retentionLeaseRef.set(shard.getRetentionLeases().get(ReplicationTracker.getPeerRecoveryRetentionLeaseId(targetShardRouting)));
        }, shardId + " validating recovery target [" + request.targetAllocationId() + "] registered ", shard, cancellableThreads, logger);
        final Closeable retentionLock = shard.acquireHistoryRetentionLock();
        resources.add(retentionLock);
        final long startingSeqNo;
        final boolean isSequenceNumberBasedRecovery = request.startingSeqNo() != SequenceNumbers.UNASSIGNED_SEQ_NO && isTargetSameHistory() && shard.hasCompleteHistoryOperations(PEER_RECOVERY_NAME, request.startingSeqNo()) && ((retentionLeaseRef.get() == null && shard.useRetentionLeasesInPeerRecovery() == false) || (retentionLeaseRef.get() != null && retentionLeaseRef.get().retainingSequenceNumber() <= request.startingSeqNo()));
        if (isSequenceNumberBasedRecovery && retentionLeaseRef.get() != null) {
            // all the history we need is retained by an existing retention lease, so we do not need a separate retention lock
            retentionLock.close();
            logger.trace("history is retained by {}", retentionLeaseRef.get());
        } else {
            // all the history we need is retained by the retention lock, obtained before calling shard.hasCompleteHistoryOperations()
            // and before acquiring the safe commit we'll be using, so we can be certain that all operations after the safe commit's
            // local checkpoint will be retained for the duration of this recovery.
            logger.trace("history is retained by retention lock");
        }
        final StepListener<SendFileResult> sendFileStep = new StepListener<>();
        final StepListener<TimeValue> prepareEngineStep = new StepListener<>();
        final StepListener<SendSnapshotResult> sendSnapshotStep = new StepListener<>();
        final StepListener<Void> finalizeStep = new StepListener<>();
        if (isSequenceNumberBasedRecovery) {
            logger.trace("performing sequence numbers based recovery. starting at [{}]", request.startingSeqNo());
            startingSeqNo = request.startingSeqNo();
            if (retentionLeaseRef.get() == null) {
                createRetentionLease(startingSeqNo, ActionListener.map(sendFileStep, ignored -> SendFileResult.EMPTY));
            } else {
                sendFileStep.onResponse(SendFileResult.EMPTY);
            }
        } else {
            final GatedCloseable<IndexCommit> wrappedSafeCommit;
            try {
                wrappedSafeCommit = acquireSafeCommit(shard);
                resources.add(wrappedSafeCommit);
            } catch (final Exception e) {
                throw new RecoveryEngineException(shard.shardId(), 1, "snapshot failed", e);
            }
            // Try and copy enough operations to the recovering peer so that if it is promoted to primary then it has a chance of being
            // able to recover other replicas using operations-based recoveries. If we are not using retention leases then we
            // conservatively copy all available operations. If we are using retention leases then "enough operations" is just the
            // operations from the local checkpoint of the safe commit onwards, because when using soft deletes the safe commit retains
            // at least as much history as anything else. The safe commit will often contain all the history retained by the current set
            // of retention leases, but this is not guaranteed: an earlier peer recovery from a different primary might have created a
            // retention lease for some history that this primary already discarded, since we discard history when the global checkpoint
            // advances and not when creating a new safe commit. In any case this is a best-effort thing since future recoveries can
            // always fall back to file-based ones, and only really presents a problem if this primary fails before things have settled
            // down.
            startingSeqNo = Long.parseLong(wrappedSafeCommit.get().getUserData().get(SequenceNumbers.LOCAL_CHECKPOINT_KEY)) + 1L;
            logger.trace("performing file-based recovery followed by history replay starting at [{}]", startingSeqNo);
            try {
                final int estimateNumOps = countNumberOfHistoryOperations(startingSeqNo);
                final Releasable releaseStore = acquireStore(shard.store());
                resources.add(releaseStore);
                sendFileStep.whenComplete(r -> IOUtils.close(wrappedSafeCommit, releaseStore), e -> {
                    try {
                        IOUtils.close(wrappedSafeCommit, releaseStore);
                    } catch (final IOException ex) {
                        logger.warn("releasing snapshot caused exception", ex);
                    }
                });
                final StepListener<ReplicationResponse> deleteRetentionLeaseStep = new StepListener<>();
                runUnderPrimaryPermit(() -> {
                    try {
                        // If the target previously had a copy of this shard then a file-based recovery might move its global
                        // checkpoint backwards. We must therefore remove any existing retention lease so that we can create a
                        // new one later on in the recovery.
                        shard.removePeerRecoveryRetentionLease(request.targetNode().getId(), new ThreadedActionListener<>(logger, shard.getThreadPool(), ThreadPool.Names.GENERIC, deleteRetentionLeaseStep, false));
                    } catch (RetentionLeaseNotFoundException e) {
                        logger.debug("no peer-recovery retention lease for " + request.targetAllocationId());
                        deleteRetentionLeaseStep.onResponse(null);
                    }
                }, shardId + " removing retention lease for [" + request.targetAllocationId() + "]", shard, cancellableThreads, logger);
                deleteRetentionLeaseStep.whenComplete(ignored -> {
                    assert Transports.assertNotTransportThread(RecoverySourceHandler.this + "[phase1]");
                    phase1(wrappedSafeCommit.get(), startingSeqNo, () -> estimateNumOps, sendFileStep);
                }, onFailure);
            } catch (final Exception e) {
                throw new RecoveryEngineException(shard.shardId(), 1, "sendFileStep failed", e);
            }
        }
        assert startingSeqNo >= 0 : "startingSeqNo must be non negative. got: " + startingSeqNo;
        sendFileStep.whenComplete(r -> {
            assert Transports.assertNotTransportThread(RecoverySourceHandler.this + "[prepareTargetForTranslog]");
            // For a sequence based recovery, the target can keep its local translog
            prepareTargetForTranslog(countNumberOfHistoryOperations(startingSeqNo), prepareEngineStep);
        }, onFailure);
        prepareEngineStep.whenComplete(prepareEngineTime -> {
            assert Transports.assertNotTransportThread(RecoverySourceHandler.this + "[phase2]");
            /*
                 * add shard to replication group (shard will receive replication requests from this point on) now that engine is open.
                 * This means that any document indexed into the primary after this will be replicated to this replica as well
                 * make sure to do this before sampling the max sequence number in the next step, to ensure that we send
                 * all documents up to maxSeqNo in phase2.
                 */
            runUnderPrimaryPermit(() -> shard.initiateTracking(request.targetAllocationId()), shardId + " initiating tracking of " + request.targetAllocationId(), shard, cancellableThreads, logger);
            final long endingSeqNo = shard.seqNoStats().getMaxSeqNo();
            if (logger.isTraceEnabled()) {
                logger.trace("snapshot translog for recovery; current size is [{}]", countNumberOfHistoryOperations(startingSeqNo));
            }
            final Translog.Snapshot phase2Snapshot = shard.newChangesSnapshot(PEER_RECOVERY_NAME, startingSeqNo, Long.MAX_VALUE, false, true);
            resources.add(phase2Snapshot);
            retentionLock.close();
            // we have to capture the max_seen_auto_id_timestamp and the max_seq_no_of_updates to make sure that these values
            // are at least as high as the corresponding values on the primary when any of these operations were executed on it.
            final long maxSeenAutoIdTimestamp = shard.getMaxSeenAutoIdTimestamp();
            final long maxSeqNoOfUpdatesOrDeletes = shard.getMaxSeqNoOfUpdatesOrDeletes();
            final RetentionLeases retentionLeases = shard.getRetentionLeases();
            final long mappingVersionOnPrimary = shard.indexSettings().getIndexMetadata().getMappingVersion();
            phase2(startingSeqNo, endingSeqNo, phase2Snapshot, maxSeenAutoIdTimestamp, maxSeqNoOfUpdatesOrDeletes, retentionLeases, mappingVersionOnPrimary, sendSnapshotStep);
        }, onFailure);
        // Recovery target can trim all operations >= startingSeqNo as we have sent all these operations in the phase 2
        final long trimAboveSeqNo = startingSeqNo - 1;
        sendSnapshotStep.whenComplete(r -> finalizeRecovery(r.targetLocalCheckpoint, trimAboveSeqNo, finalizeStep), onFailure);
        finalizeStep.whenComplete(r -> {
            // TODO: return the actual throttle time
            final long phase1ThrottlingWaitTime = 0L;
            final SendSnapshotResult sendSnapshotResult = sendSnapshotStep.result();
            final SendFileResult sendFileResult = sendFileStep.result();
            final RecoveryResponse response = new RecoveryResponse(sendFileResult.phase1FileNames, sendFileResult.phase1FileSizes, sendFileResult.phase1ExistingFileNames, sendFileResult.phase1ExistingFileSizes, sendFileResult.totalSize, sendFileResult.existingTotalSize, sendFileResult.took.millis(), phase1ThrottlingWaitTime, prepareEngineStep.result().millis(), sendSnapshotResult.sentOperations, sendSnapshotResult.tookTime.millis());
            try {
                future.onResponse(response);
            } finally {
                IOUtils.close(resources);
            }
        }, onFailure);
    } catch (Exception e) {
        IOUtils.closeWhileHandlingException(releaseResources, () -> future.onFailure(e));
    }
}
Also used : SequenceNumbers(org.opensearch.index.seqno.SequenceNumbers) Arrays(java.util.Arrays) IndexFormatTooNewException(org.apache.lucene.index.IndexFormatTooNewException) RecoveryEngineException(org.opensearch.index.engine.RecoveryEngineException) FutureUtils(org.opensearch.common.util.concurrent.FutureUtils) Releasables(org.opensearch.common.lease.Releasables) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Locale(java.util.Locale) ActionListener(org.opensearch.action.ActionListener) IOContext(org.apache.lucene.store.IOContext) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) TimeValue(org.opensearch.common.unit.TimeValue) RemoteTransportException(org.opensearch.transport.RemoteTransportException) ExceptionsHelper(org.opensearch.ExceptionsHelper) ReplicationTracker(org.opensearch.index.seqno.ReplicationTracker) IndexShardClosedException(org.opensearch.index.shard.IndexShardClosedException) Store(org.opensearch.index.store.Store) GatedCloseable(org.opensearch.common.concurrent.GatedCloseable) List(java.util.List) Logger(org.apache.logging.log4j.Logger) BytesArray(org.opensearch.common.bytes.BytesArray) CheckedRunnable(org.opensearch.common.CheckedRunnable) ReplicationResponse(org.opensearch.action.support.replication.ReplicationResponse) StepListener(org.opensearch.action.StepListener) ListenableFuture(org.opensearch.common.util.concurrent.ListenableFuture) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) IndexCommit(org.apache.lucene.index.IndexCommit) CancellableThreads(org.opensearch.common.util.CancellableThreads) IndexShardState(org.opensearch.index.shard.IndexShardState) BytesReference(org.opensearch.common.bytes.BytesReference) ActionRunnable(org.opensearch.action.ActionRunnable) ThreadPool(org.opensearch.threadpool.ThreadPool) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ByteSizeValue(org.opensearch.common.unit.ByteSizeValue) CompletableFuture(java.util.concurrent.CompletableFuture) Releasable(org.opensearch.common.lease.Releasable) ThreadedActionListener(org.opensearch.action.support.ThreadedActionListener) Deque(java.util.Deque) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) OpenSearchExecutors(org.opensearch.common.util.concurrent.OpenSearchExecutors) ArrayList(java.util.ArrayList) IndexShard(org.opensearch.index.shard.IndexShard) Loggers(org.opensearch.common.logging.Loggers) LegacyESVersion(org.opensearch.LegacyESVersion) Translog(org.opensearch.index.translog.Translog) StreamSupport(java.util.stream.StreamSupport) StoreFileMetadata(org.opensearch.index.store.StoreFileMetadata) IntSupplier(java.util.function.IntSupplier) RetentionLease(org.opensearch.index.seqno.RetentionLease) ArrayUtil(org.apache.lucene.util.ArrayUtil) StopWatch(org.opensearch.common.StopWatch) InputStreamIndexInput(org.opensearch.common.lucene.store.InputStreamIndexInput) IndexInput(org.apache.lucene.store.IndexInput) SetOnce(org.apache.lucene.util.SetOnce) IOException(java.io.IOException) IndexFormatTooOldException(org.apache.lucene.index.IndexFormatTooOldException) IndexShardRelocatedException(org.opensearch.index.shard.IndexShardRelocatedException) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) ShardRouting(org.opensearch.cluster.routing.ShardRouting) IOUtils(org.opensearch.core.internal.io.IOUtils) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) Transports(org.opensearch.transport.Transports) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) Closeable(java.io.Closeable) Comparator(java.util.Comparator) Collections(java.util.Collections) RateLimiter(org.apache.lucene.store.RateLimiter) RetentionLeaseNotFoundException(org.opensearch.index.seqno.RetentionLeaseNotFoundException) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) GatedCloseable(org.opensearch.common.concurrent.GatedCloseable) Closeable(java.io.Closeable) ReplicationResponse(org.opensearch.action.support.replication.ReplicationResponse) Translog(org.opensearch.index.translog.Translog) RecoveryEngineException(org.opensearch.index.engine.RecoveryEngineException) TimeValue(org.opensearch.common.unit.TimeValue) CancellableThreads(org.opensearch.common.util.CancellableThreads) SetOnce(org.apache.lucene.util.SetOnce) IOException(java.io.IOException) IndexFormatTooNewException(org.apache.lucene.index.IndexFormatTooNewException) RecoveryEngineException(org.opensearch.index.engine.RecoveryEngineException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) RemoteTransportException(org.opensearch.transport.RemoteTransportException) IndexShardClosedException(org.opensearch.index.shard.IndexShardClosedException) IOException(java.io.IOException) IndexFormatTooOldException(org.apache.lucene.index.IndexFormatTooOldException) IndexShardRelocatedException(org.opensearch.index.shard.IndexShardRelocatedException) RetentionLeaseNotFoundException(org.opensearch.index.seqno.RetentionLeaseNotFoundException) IndexCommit(org.apache.lucene.index.IndexCommit) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) RetentionLeaseNotFoundException(org.opensearch.index.seqno.RetentionLeaseNotFoundException) IndexShardClosedException(org.opensearch.index.shard.IndexShardClosedException) RetentionLease(org.opensearch.index.seqno.RetentionLease) StepListener(org.opensearch.action.StepListener) Releasable(org.opensearch.common.lease.Releasable) ShardRouting(org.opensearch.cluster.routing.ShardRouting)

Example 7 with RetentionLeases

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

the class InternalEngineTests method testKeepMinRetainedSeqNoByMergePolicy.

public void testKeepMinRetainedSeqNoByMergePolicy() throws IOException {
    IOUtils.close(engine, store);
    Settings.Builder settings = Settings.builder().put(defaultSettings.getSettings()).put(IndexSettings.INDEX_SOFT_DELETES_RETENTION_OPERATIONS_SETTING.getKey(), randomLongBetween(0, 10));
    final IndexMetadata indexMetadata = IndexMetadata.builder(defaultSettings.getIndexMetadata()).settings(settings).build();
    final IndexSettings indexSettings = IndexSettingsModule.newIndexSettings(indexMetadata);
    final AtomicLong globalCheckpoint = new AtomicLong(SequenceNumbers.NO_OPS_PERFORMED);
    final long primaryTerm = randomLongBetween(1, Long.MAX_VALUE);
    final AtomicLong retentionLeasesVersion = new AtomicLong();
    final AtomicReference<RetentionLeases> retentionLeasesHolder = new AtomicReference<>(new RetentionLeases(primaryTerm, retentionLeasesVersion.get(), Collections.emptyList()));
    final List<Engine.Operation> operations = generateSingleDocHistory(true, randomFrom(VersionType.INTERNAL, VersionType.EXTERNAL), 2, 10, 300, "2");
    Randomness.shuffle(operations);
    Set<Long> existingSeqNos = new HashSet<>();
    store = createStore();
    engine = createEngine(config(indexSettings, store, createTempDir(), newMergePolicy(), null, null, globalCheckpoint::get, retentionLeasesHolder::get));
    assertThat(engine.getMinRetainedSeqNo(), equalTo(0L));
    long lastMinRetainedSeqNo = engine.getMinRetainedSeqNo();
    for (Engine.Operation op : operations) {
        final Engine.Result result;
        if (op instanceof Engine.Index) {
            result = engine.index((Engine.Index) op);
        } else {
            result = engine.delete((Engine.Delete) op);
        }
        existingSeqNos.add(result.getSeqNo());
        if (randomBoolean()) {
            // advance persisted local checkpoint
            engine.syncTranslog();
            assertEquals(engine.getProcessedLocalCheckpoint(), engine.getPersistedLocalCheckpoint());
            globalCheckpoint.set(randomLongBetween(globalCheckpoint.get(), engine.getLocalCheckpointTracker().getPersistedCheckpoint()));
        }
        if (randomBoolean()) {
            retentionLeasesVersion.incrementAndGet();
            final int length = randomIntBetween(0, 8);
            final List<RetentionLease> leases = new ArrayList<>(length);
            for (int i = 0; i < length; i++) {
                final String id = randomAlphaOfLength(8);
                final long retainingSequenceNumber = randomLongBetween(0, Math.max(0, globalCheckpoint.get()));
                final long timestamp = randomLongBetween(0L, Long.MAX_VALUE);
                final String source = randomAlphaOfLength(8);
                leases.add(new RetentionLease(id, retainingSequenceNumber, timestamp, source));
            }
            retentionLeasesHolder.set(new RetentionLeases(primaryTerm, retentionLeasesVersion.get(), leases));
        }
        if (rarely()) {
            settings.put(IndexSettings.INDEX_SOFT_DELETES_RETENTION_OPERATIONS_SETTING.getKey(), randomLongBetween(0, 10));
            indexSettings.updateIndexMetadata(IndexMetadata.builder(defaultSettings.getIndexMetadata()).settings(settings).build());
            engine.onSettingsChanged(indexSettings.getTranslogRetentionAge(), indexSettings.getTranslogRetentionSize(), indexSettings.getSoftDeleteRetentionOperations());
        }
        if (rarely()) {
            engine.refresh("test");
        }
        if (rarely()) {
            engine.flush(true, true);
            assertThat(Long.parseLong(engine.getLastCommittedSegmentInfos().userData.get(Engine.MIN_RETAINED_SEQNO)), equalTo(engine.getMinRetainedSeqNo()));
        }
        if (rarely()) {
            engine.forceMerge(randomBoolean(), 1, false, false, false, UUIDs.randomBase64UUID());
        }
        try (Closeable ignored = engine.acquireHistoryRetentionLock()) {
            long minRetainSeqNos = engine.getMinRetainedSeqNo();
            assertThat(minRetainSeqNos, lessThanOrEqualTo(globalCheckpoint.get() + 1));
            Long[] expectedOps = existingSeqNos.stream().filter(seqno -> seqno >= minRetainSeqNos).toArray(Long[]::new);
            Set<Long> actualOps = readAllOperationsInLucene(engine).stream().map(Translog.Operation::seqNo).collect(Collectors.toSet());
            assertThat(actualOps, containsInAnyOrder(expectedOps));
        }
        try (GatedCloseable<IndexCommit> wrappedSafeCommit = engine.acquireSafeIndexCommit()) {
            IndexCommit safeCommit = wrappedSafeCommit.get();
            if (safeCommit.getUserData().containsKey(Engine.MIN_RETAINED_SEQNO)) {
                lastMinRetainedSeqNo = Long.parseLong(safeCommit.getUserData().get(Engine.MIN_RETAINED_SEQNO));
            }
        }
    }
    if (randomBoolean()) {
        engine.close();
    } else {
        engine.flushAndClose();
    }
    try (InternalEngine recoveringEngine = new InternalEngine(engine.config())) {
        assertThat(recoveringEngine.getMinRetainedSeqNo(), equalTo(lastMinRetainedSeqNo));
    }
}
Also used : NoMergePolicy(org.apache.lucene.index.NoMergePolicy) SeqNoStats(org.opensearch.index.seqno.SeqNoStats) SequenceNumbers(org.opensearch.index.seqno.SequenceNumbers) Arrays(java.util.Arrays) LongSupplier(java.util.function.LongSupplier) Term(org.apache.lucene.index.Term) Matchers.not(org.hamcrest.Matchers.not) Level(org.apache.logging.log4j.Level) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) Version(org.opensearch.Version) PEER_RECOVERY(org.opensearch.index.engine.Engine.Operation.Origin.PEER_RECOVERY) LogEvent(org.apache.logging.log4j.core.LogEvent) ReferenceManager(org.apache.lucene.search.ReferenceManager) Document(org.opensearch.index.mapper.ParseContext.Document) Strings(org.opensearch.common.Strings) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) RandomNumbers(com.carrotsearch.randomizedtesting.generators.RandomNumbers) REPLICA(org.opensearch.index.engine.Engine.Operation.Origin.REPLICA) MergePolicy(org.apache.lucene.index.MergePolicy) TermsEnum(org.apache.lucene.index.TermsEnum) Map(java.util.Map) Matchers.nullValue(org.hamcrest.Matchers.nullValue) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Lucene(org.opensearch.common.lucene.Lucene) DefaultTranslogDeletionPolicy(org.opensearch.index.translog.DefaultTranslogDeletionPolicy) ActionListener(org.opensearch.action.ActionListener) SequentialStoredFieldsLeafReader(org.opensearch.common.lucene.index.SequentialStoredFieldsLeafReader) FieldsVisitor(org.opensearch.index.fieldvisitor.FieldsVisitor) Path(java.nio.file.Path) NumericDocValuesField(org.apache.lucene.document.NumericDocValuesField) TimeValue(org.opensearch.common.unit.TimeValue) NO_OPS_PERFORMED(org.opensearch.index.seqno.SequenceNumbers.NO_OPS_PERFORMED) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) SoftDeletesRetentionMergePolicy(org.apache.lucene.index.SoftDeletesRetentionMergePolicy) Mockito.atLeastOnce(org.mockito.Mockito.atLeastOnce) Set(java.util.Set) SortedSetSortField(org.apache.lucene.search.SortedSetSortField) Settings(org.opensearch.common.settings.Settings) ReplicationTracker(org.opensearch.index.seqno.ReplicationTracker) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) PointValues(org.apache.lucene.index.PointValues) UncheckedIOException(java.io.UncheckedIOException) CountDownLatch(java.util.concurrent.CountDownLatch) VersionType(org.opensearch.index.VersionType) Logger(org.apache.logging.log4j.Logger) Matchers.contains(org.hamcrest.Matchers.contains) Randomness(org.opensearch.common.Randomness) BytesArray(org.opensearch.common.bytes.BytesArray) CheckedRunnable(org.opensearch.common.CheckedRunnable) LocalCheckpointTracker(org.opensearch.index.seqno.LocalCheckpointTracker) DocIdAndSeqNo(org.opensearch.common.lucene.uid.VersionsAndSeqNoResolver.DocIdAndSeqNo) 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) TriFunction(org.opensearch.common.TriFunction) Mockito.mock(org.mockito.Mockito.mock) IndexCommit(org.apache.lucene.index.IndexCommit) CodecService(org.opensearch.index.codec.CodecService) LiveIndexWriterConfig(org.apache.lucene.index.LiveIndexWriterConfig) TranslogDeletionPolicies.createTranslogDeletionPolicy(org.opensearch.index.translog.TranslogDeletionPolicies.createTranslogDeletionPolicy) ThreadPool(org.opensearch.threadpool.ThreadPool) LogDocMergePolicy(org.apache.lucene.index.LogDocMergePolicy) FixedBitSet(org.apache.lucene.util.FixedBitSet) RegexFilter(org.apache.logging.log4j.core.filter.RegexFilter) Mockito.spy(org.mockito.Mockito.spy) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) ToLongBiFunction(java.util.function.ToLongBiFunction) UNASSIGNED_SEQ_NO(org.opensearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO) Lock(org.apache.lucene.store.Lock) 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) Bits(org.apache.lucene.util.Bits) TieredMergePolicy(org.apache.lucene.index.TieredMergePolicy) TopDocs(org.apache.lucene.search.TopDocs) ParseContext(org.opensearch.index.mapper.ParseContext) Versions(org.opensearch.common.lucene.uid.Versions) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) LongStream(java.util.stream.LongStream) SetOnce(org.apache.lucene.util.SetOnce) Files(java.nio.file.Files) AbstractAppender(org.apache.logging.log4j.core.appender.AbstractAppender) TestTranslog(org.opensearch.index.translog.TestTranslog) IOException(java.io.IOException) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) Mockito.times(org.mockito.Mockito.times) UNASSIGNED_PRIMARY_TERM(org.opensearch.index.seqno.SequenceNumbers.UNASSIGNED_PRIMARY_TERM) SourceFieldMapper(org.opensearch.index.mapper.SourceFieldMapper) AtomicLong(java.util.concurrent.atomic.AtomicLong) Matchers.hasItem(org.hamcrest.Matchers.hasItem) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) SnapshotMatchers(org.opensearch.index.translog.SnapshotMatchers) Phaser(java.util.concurrent.Phaser) LOCAL_TRANSLOG_RECOVERY(org.opensearch.index.engine.Engine.Operation.Origin.LOCAL_TRANSLOG_RECOVERY) MockDirectoryWrapper(org.apache.lucene.tests.store.MockDirectoryWrapper) TextField(org.apache.lucene.document.TextField) SeqNoFieldMapper(org.opensearch.index.mapper.SeqNoFieldMapper) Collections.shuffle(java.util.Collections.shuffle) IdFieldMapper(org.opensearch.index.mapper.IdFieldMapper) Matchers.emptyArray(org.hamcrest.Matchers.emptyArray) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) IndexableField(org.apache.lucene.index.IndexableField) BiFunction(java.util.function.BiFunction) NoneCircuitBreakerService(org.opensearch.indices.breaker.NoneCircuitBreakerService) StoredField(org.apache.lucene.document.StoredField) OpenSearchException(org.opensearch.OpenSearchException) Matchers.hasKey(org.hamcrest.Matchers.hasKey) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) ObjectObjectCursor(com.carrotsearch.hppc.cursors.ObjectObjectCursor) Matchers.everyItem(org.hamcrest.Matchers.everyItem) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Directory(org.apache.lucene.store.Directory) LeafReaderContext(org.apache.lucene.index.LeafReaderContext) TotalHitCountCollector(org.apache.lucene.search.TotalHitCountCollector) IndexShardRoutingTable(org.opensearch.cluster.routing.IndexShardRoutingTable) CyclicBarrier(java.util.concurrent.CyclicBarrier) Terms(org.apache.lucene.index.Terms) Sort(org.apache.lucene.search.Sort) BytesRef(org.apache.lucene.util.BytesRef) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) DirectoryReader(org.apache.lucene.index.DirectoryReader) TranslogConfig(org.opensearch.index.translog.TranslogConfig) TranslogDeletionPolicyFactory(org.opensearch.index.translog.TranslogDeletionPolicyFactory) Store(org.opensearch.index.store.Store) Collectors(java.util.stream.Collectors) SegmentInfos(org.apache.lucene.index.SegmentInfos) Tuple(org.opensearch.common.collect.Tuple) IndexWriter(org.apache.lucene.index.IndexWriter) GatedCloseable(org.opensearch.common.concurrent.GatedCloseable) List(java.util.List) MatcherAssert(org.hamcrest.MatcherAssert) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) Matchers.equalTo(org.hamcrest.Matchers.equalTo) LeafReader(org.apache.lucene.index.LeafReader) IndexSettings(org.opensearch.index.IndexSettings) ShardUtils(org.opensearch.index.shard.ShardUtils) Queue(java.util.Queue) BigArrays(org.opensearch.common.util.BigArrays) IndexWriterConfig(org.apache.lucene.index.IndexWriterConfig) IndexReader(org.apache.lucene.index.IndexReader) IndexSearcher(org.apache.lucene.search.IndexSearcher) Uid(org.opensearch.index.mapper.Uid) IndexSettingsModule(org.opensearch.test.IndexSettingsModule) LongPoint(org.apache.lucene.document.LongPoint) BytesReference(org.opensearch.common.bytes.BytesReference) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) NumericDocValues(org.apache.lucene.index.NumericDocValues) CheckedBiConsumer(org.opensearch.common.CheckedBiConsumer) LOCAL_RESET(org.opensearch.index.engine.Engine.Operation.Origin.LOCAL_RESET) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ByteSizeValue(org.opensearch.common.unit.ByteSizeValue) HashMap(java.util.HashMap) ReleasableLock(org.opensearch.common.util.concurrent.ReleasableLock) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) HashSet(java.util.HashSet) Loggers(org.opensearch.common.logging.Loggers) Charset(java.nio.charset.Charset) Translog(org.opensearch.index.translog.Translog) PRIMARY(org.opensearch.index.engine.Engine.Operation.Origin.PRIMARY) UUIDs(org.opensearch.common.UUIDs) IntSupplier(java.util.function.IntSupplier) RetentionLease(org.opensearch.index.seqno.RetentionLease) CoreMatchers.sameInstance(org.hamcrest.CoreMatchers.sameInstance) OpenSearchDirectoryReader(org.opensearch.common.lucene.index.OpenSearchDirectoryReader) Matchers.empty(org.hamcrest.Matchers.empty) Iterator(java.util.Iterator) Semaphore(java.util.concurrent.Semaphore) Matchers(org.hamcrest.Matchers) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) ShardRouting(org.opensearch.cluster.routing.ShardRouting) IOUtils(org.opensearch.core.internal.io.IOUtils) ShardId(org.opensearch.index.shard.ShardId) TimeUnit(java.util.concurrent.TimeUnit) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) TermQuery(org.apache.lucene.search.TermQuery) VersionsAndSeqNoResolver(org.opensearch.common.lucene.uid.VersionsAndSeqNoResolver) Field(org.apache.lucene.document.Field) TransportActions(org.opensearch.action.support.TransportActions) Closeable(java.io.Closeable) IndexRequest(org.opensearch.action.index.IndexRequest) Comparator(java.util.Comparator) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) IndexSettings(org.opensearch.index.IndexSettings) GatedCloseable(org.opensearch.common.concurrent.GatedCloseable) Closeable(java.io.Closeable) ArrayList(java.util.ArrayList) Matchers.containsString(org.hamcrest.Matchers.containsString) TestTranslog(org.opensearch.index.translog.TestTranslog) Translog(org.opensearch.index.translog.Translog) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings) HashSet(java.util.HashSet) AtomicReference(java.util.concurrent.atomic.AtomicReference) LongPoint(org.apache.lucene.document.LongPoint) IndexCommit(org.apache.lucene.index.IndexCommit) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) AtomicLong(java.util.concurrent.atomic.AtomicLong) RetentionLease(org.opensearch.index.seqno.RetentionLease) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 8 with RetentionLeases

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

the class EngineConfigFactoryTests method testCreateCodecServiceFromFactory.

public void testCreateCodecServiceFromFactory() {
    IndexMetadata meta = IndexMetadata.builder("test").settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1).build();
    List<EnginePlugin> plugins = Arrays.asList(new BakEnginePlugin());
    IndexSettings indexSettings = IndexSettingsModule.newIndexSettings("test", meta.getSettings());
    EngineConfigFactory factory = new EngineConfigFactory(plugins, indexSettings);
    EngineConfig config = factory.newEngineConfig(null, null, indexSettings, null, null, null, null, null, null, null, null, null, null, TimeValue.timeValueMinutes(5), null, null, null, null, null, () -> new RetentionLeases(0, 0, Collections.emptyList()), null, null, false);
    assertNotNull(config.getCodec());
}
Also used : EnginePlugin(org.opensearch.plugins.EnginePlugin) IndexSettings(org.opensearch.index.IndexSettings) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) RetentionLeases(org.opensearch.index.seqno.RetentionLeases)

Example 9 with RetentionLeases

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

the class SoftDeletesPolicyTests method testWhenLocalCheckpointOfSafeCommitDictatesThePolicy.

public void testWhenLocalCheckpointOfSafeCommitDictatesThePolicy() {
    final int retentionOperations = randomIntBetween(0, 1024);
    final long localCheckpointOfSafeCommit = randomLongBetween(-1, Long.MAX_VALUE - retentionOperations - 1);
    final AtomicLong globalCheckpoint = new AtomicLong(randomLongBetween(Math.max(0, localCheckpointOfSafeCommit + retentionOperations), Long.MAX_VALUE - 1));
    final Collection<RetentionLease> leases = new ArrayList<>();
    final int numberOfLeases = randomIntBetween(0, 16);
    for (int i = 0; i < numberOfLeases; i++) {
        leases.add(new RetentionLease(Integer.toString(i), // leases are for more than the local checkpoint
        randomLongBetween(1 + localCheckpointOfSafeCommit + 1, Long.MAX_VALUE), randomNonNegativeLong(), "test"));
    }
    final long primaryTerm = randomNonNegativeLong();
    final long version = randomNonNegativeLong();
    final Supplier<RetentionLeases> leasesSupplier = () -> new RetentionLeases(primaryTerm, version, Collections.unmodifiableCollection(new ArrayList<>(leases)));
    final SoftDeletesPolicy policy = new SoftDeletesPolicy(globalCheckpoint::get, 0, retentionOperations, leasesSupplier);
    policy.setLocalCheckpointOfSafeCommit(localCheckpointOfSafeCommit);
    assertThat(policy.getMinRetainedSeqNo(), equalTo(1 + localCheckpointOfSafeCommit));
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) RetentionLease(org.opensearch.index.seqno.RetentionLease) ArrayList(java.util.ArrayList) LongPoint(org.apache.lucene.document.LongPoint) RetentionLeases(org.opensearch.index.seqno.RetentionLeases)

Example 10 with RetentionLeases

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

the class SoftDeletesPolicyTests method testWhenGlobalCheckpointDictatesThePolicy.

public void testWhenGlobalCheckpointDictatesThePolicy() {
    final int retentionOperations = randomIntBetween(0, 1024);
    final AtomicLong globalCheckpoint = new AtomicLong(randomLongBetween(0, Long.MAX_VALUE - 2));
    final Collection<RetentionLease> leases = new ArrayList<>();
    final int numberOfLeases = randomIntBetween(0, 16);
    for (int i = 0; i < numberOfLeases; i++) {
        // setup leases where the minimum retained sequence number is more than the policy dictated by the global checkpoint
        leases.add(new RetentionLease(Integer.toString(i), randomLongBetween(1 + globalCheckpoint.get() - retentionOperations + 1, Long.MAX_VALUE), randomNonNegativeLong(), "test"));
    }
    final long primaryTerm = randomNonNegativeLong();
    final long version = randomNonNegativeLong();
    final Supplier<RetentionLeases> leasesSupplier = () -> new RetentionLeases(primaryTerm, version, Collections.unmodifiableCollection(new ArrayList<>(leases)));
    final SoftDeletesPolicy policy = new SoftDeletesPolicy(globalCheckpoint::get, 0, retentionOperations, leasesSupplier);
    // set the local checkpoint of the safe commit to more than the policy dicated by the global checkpoint
    final long localCheckpointOfSafeCommit = randomLongBetween(1 + globalCheckpoint.get() - retentionOperations + 1, Long.MAX_VALUE);
    policy.setLocalCheckpointOfSafeCommit(localCheckpointOfSafeCommit);
    assertThat(policy.getMinRetainedSeqNo(), equalTo(1 + globalCheckpoint.get() - retentionOperations));
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) RetentionLease(org.opensearch.index.seqno.RetentionLease) ArrayList(java.util.ArrayList) LongPoint(org.apache.lucene.document.LongPoint) RetentionLeases(org.opensearch.index.seqno.RetentionLeases)

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