Search in sources :

Example 1 with ReplicationLuceneIndex

use of org.opensearch.indices.replication.common.ReplicationLuceneIndex in project OpenSearch by opensearch-project.

the class StoreRecovery method recoveryListener.

private ActionListener<Boolean> recoveryListener(IndexShard indexShard, ActionListener<Boolean> listener) {
    return ActionListener.wrap(res -> {
        if (res) {
            // Check that the gateway didn't leave the shard in init or recovering stage. it is up to the gateway
            // to call post recovery.
            final IndexShardState shardState = indexShard.state();
            final RecoveryState recoveryState = indexShard.recoveryState();
            assert shardState != IndexShardState.CREATED && shardState != IndexShardState.RECOVERING : "recovery process of " + shardId + " didn't get to post_recovery. shardState [" + shardState + "]";
            if (logger.isTraceEnabled()) {
                ReplicationLuceneIndex index = recoveryState.getIndex();
                StringBuilder sb = new StringBuilder();
                sb.append("    index    : files           [").append(index.totalFileCount()).append("] with total_size [").append(new ByteSizeValue(index.totalBytes())).append("], took[").append(TimeValue.timeValueMillis(index.time())).append("]\n");
                sb.append("             : recovered_files [").append(index.recoveredFileCount()).append("] with total_size [").append(new ByteSizeValue(index.recoveredBytes())).append("]\n");
                sb.append("             : reusing_files   [").append(index.reusedFileCount()).append("] with total_size [").append(new ByteSizeValue(index.reusedBytes())).append("]\n");
                sb.append("    verify_index    : took [").append(TimeValue.timeValueMillis(recoveryState.getVerifyIndex().time())).append("], check_index [").append(timeValueMillis(recoveryState.getVerifyIndex().checkIndexTime())).append("]\n");
                sb.append("    translog : number_of_operations [").append(recoveryState.getTranslog().recoveredOperations()).append("], took [").append(TimeValue.timeValueMillis(recoveryState.getTranslog().time())).append("]");
                logger.trace("recovery completed from [shard_store], took [{}]\n{}", timeValueMillis(recoveryState.getTimer().time()), sb);
            } else if (logger.isDebugEnabled()) {
                logger.debug("recovery completed from [shard_store], took [{}]", timeValueMillis(recoveryState.getTimer().time()));
            }
        }
        listener.onResponse(res);
    }, ex -> {
        if (ex instanceof IndexShardRecoveryException) {
            if (indexShard.state() == IndexShardState.CLOSED) {
                // got closed on us, just ignore this recovery
                listener.onResponse(false);
                return;
            }
            if ((ex.getCause() instanceof IndexShardClosedException) || (ex.getCause() instanceof IndexShardNotStartedException)) {
                // got closed on us, just ignore this recovery
                listener.onResponse(false);
                return;
            }
            listener.onFailure(ex);
        } else if (ex instanceof IndexShardClosedException || ex instanceof IndexShardNotStartedException) {
            listener.onResponse(false);
        } else {
            if (indexShard.state() == IndexShardState.CLOSED) {
                // got closed on us, just ignore this recovery
                listener.onResponse(false);
            } else {
                listener.onFailure(new IndexShardRecoveryException(shardId, "failed recovery", ex));
            }
        }
    });
}
Also used : ReplicationLuceneIndex(org.opensearch.indices.replication.common.ReplicationLuceneIndex) ByteSizeValue(org.opensearch.common.unit.ByteSizeValue) RecoveryState(org.opensearch.indices.recovery.RecoveryState)

Example 2 with ReplicationLuceneIndex

use of org.opensearch.indices.replication.common.ReplicationLuceneIndex in project OpenSearch by opensearch-project.

the class RecoveryTarget method receiveFileInfo.

@Override
public void receiveFileInfo(List<String> phase1FileNames, List<Long> phase1FileSizes, List<String> phase1ExistingFileNames, List<Long> phase1ExistingFileSizes, int totalTranslogOps, ActionListener<Void> listener) {
    ActionListener.completeWith(listener, () -> {
        indexShard.resetRecoveryStage();
        indexShard.prepareForIndexRecovery();
        final ReplicationLuceneIndex index = state().getIndex();
        for (int i = 0; i < phase1ExistingFileNames.size(); i++) {
            index.addFileDetail(phase1ExistingFileNames.get(i), phase1ExistingFileSizes.get(i), true);
        }
        for (int i = 0; i < phase1FileNames.size(); i++) {
            index.addFileDetail(phase1FileNames.get(i), phase1FileSizes.get(i), false);
        }
        index.setFileDetailsComplete();
        state().getTranslog().totalOperations(totalTranslogOps);
        state().getTranslog().totalOperationsOnStart(totalTranslogOps);
        return null;
    });
}
Also used : ReplicationLuceneIndex(org.opensearch.indices.replication.common.ReplicationLuceneIndex)

Example 3 with ReplicationLuceneIndex

use of org.opensearch.indices.replication.common.ReplicationLuceneIndex in project OpenSearch by opensearch-project.

the class RecoveryTargetTests method testConcurrentModificationIndexFileDetailsMap.

public void testConcurrentModificationIndexFileDetailsMap() throws InterruptedException {
    final ReplicationLuceneIndex index = new ReplicationLuceneIndex();
    final AtomicBoolean stop = new AtomicBoolean(false);
    Streamer<ReplicationLuceneIndex> readWriteIndex = new Streamer<ReplicationLuceneIndex>(stop, index) {

        @Override
        ReplicationLuceneIndex createObj(StreamInput in) throws IOException {
            return new ReplicationLuceneIndex(in);
        }
    };
    Thread modifyThread = new Thread() {

        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                index.addFileDetail(randomAlphaOfLength(10), 100, true);
            }
            stop.set(true);
        }
    };
    readWriteIndex.start();
    modifyThread.start();
    modifyThread.join();
    readWriteIndex.join();
    assertThat(readWriteIndex.error.get(), equalTo(null));
}
Also used : ReplicationLuceneIndex(org.opensearch.indices.replication.common.ReplicationLuceneIndex) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) StreamInput(org.opensearch.common.io.stream.StreamInput)

Example 4 with ReplicationLuceneIndex

use of org.opensearch.indices.replication.common.ReplicationLuceneIndex in project OpenSearch by opensearch-project.

the class RecoverySourceHandlerTests method testSendFiles.

public void testSendFiles() throws Throwable {
    final RecoverySettings recoverySettings = new RecoverySettings(Settings.EMPTY, service);
    final StartRecoveryRequest request = getStartRecoveryRequest();
    Store store = newStore(createTempDir());
    Directory dir = store.directory();
    RandomIndexWriter writer = new RandomIndexWriter(random(), dir, newIndexWriterConfig());
    int numDocs = randomIntBetween(10, 100);
    for (int i = 0; i < numDocs; i++) {
        Document document = new Document();
        document.add(new StringField("id", Integer.toString(i), Field.Store.YES));
        document.add(newField("field", randomUnicodeOfCodepointLengthBetween(1, 10), TextField.TYPE_STORED));
        writer.addDocument(document);
    }
    writer.commit();
    writer.close();
    Store.MetadataSnapshot metadata = store.getMetadata();
    ReplicationLuceneIndex luceneIndex = new ReplicationLuceneIndex();
    List<StoreFileMetadata> metas = new ArrayList<>();
    for (StoreFileMetadata md : metadata) {
        metas.add(md);
        luceneIndex.addFileDetail(md.name(), md.length(), false);
    }
    Store targetStore = newStore(createTempDir());
    MultiFileWriter multiFileWriter = new MultiFileWriter(targetStore, luceneIndex, "", logger, () -> {
    });
    RecoveryTargetHandler target = new TestRecoveryTargetHandler() {

        @Override
        public void writeFileChunk(StoreFileMetadata md, long position, BytesReference content, boolean lastChunk, int totalTranslogOps, ActionListener<Void> listener) {
            ActionListener.completeWith(listener, () -> {
                multiFileWriter.writeFileChunk(md, position, content, lastChunk);
                return null;
            });
        }
    };
    RecoverySourceHandler handler = new RecoverySourceHandler(null, new AsyncRecoveryTarget(target, recoveryExecutor), threadPool, request, Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 5), between(1, 5));
    PlainActionFuture<Void> sendFilesFuture = new PlainActionFuture<>();
    handler.sendFiles(store, metas.toArray(new StoreFileMetadata[0]), () -> 0, sendFilesFuture);
    sendFilesFuture.actionGet();
    Store.MetadataSnapshot targetStoreMetadata = targetStore.getMetadata();
    Store.RecoveryDiff recoveryDiff = targetStoreMetadata.recoveryDiff(metadata);
    assertEquals(metas.size(), recoveryDiff.identical.size());
    assertEquals(0, recoveryDiff.different.size());
    assertEquals(0, recoveryDiff.missing.size());
    IndexReader reader = DirectoryReader.open(targetStore.directory());
    assertEquals(numDocs, reader.maxDoc());
    IOUtils.close(reader, store, multiFileWriter, targetStore);
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Store(org.opensearch.index.store.Store) StoreFileMetadata(org.opensearch.index.store.StoreFileMetadata) Document(org.apache.lucene.document.Document) ParsedDocument(org.opensearch.index.mapper.ParsedDocument) Directory(org.apache.lucene.store.Directory) BytesReference(org.opensearch.common.bytes.BytesReference) ReplicationLuceneIndex(org.opensearch.indices.replication.common.ReplicationLuceneIndex) LatchedActionListener(org.opensearch.action.LatchedActionListener) ActionListener(org.opensearch.action.ActionListener) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) StringField(org.apache.lucene.document.StringField) IndexReader(org.apache.lucene.index.IndexReader) RandomIndexWriter(org.apache.lucene.tests.index.RandomIndexWriter)

Example 5 with ReplicationLuceneIndex

use of org.opensearch.indices.replication.common.ReplicationLuceneIndex in project OpenSearch by opensearch-project.

the class RecoverySourceHandlerTests method testHandleCorruptedIndexOnSendSendFiles.

public void testHandleCorruptedIndexOnSendSendFiles() throws Throwable {
    Settings settings = Settings.builder().put("indices.recovery.concurrent_streams", 1).put("indices.recovery.concurrent_small_file_streams", 1).build();
    final RecoverySettings recoverySettings = new RecoverySettings(settings, service);
    final StartRecoveryRequest request = getStartRecoveryRequest();
    Path tempDir = createTempDir();
    Store store = newStore(tempDir, false);
    AtomicBoolean failedEngine = new AtomicBoolean(false);
    Directory dir = store.directory();
    RandomIndexWriter writer = new RandomIndexWriter(random(), dir, newIndexWriterConfig());
    int numDocs = randomIntBetween(10, 100);
    for (int i = 0; i < numDocs; i++) {
        Document document = new Document();
        document.add(new StringField("id", Integer.toString(i), Field.Store.YES));
        document.add(newField("field", randomUnicodeOfCodepointLengthBetween(1, 10), TextField.TYPE_STORED));
        writer.addDocument(document);
    }
    writer.commit();
    writer.close();
    ReplicationLuceneIndex luceneIndex = new ReplicationLuceneIndex();
    Store.MetadataSnapshot metadata = store.getMetadata();
    List<StoreFileMetadata> metas = new ArrayList<>();
    for (StoreFileMetadata md : metadata) {
        metas.add(md);
        luceneIndex.addFileDetail(md.name(), md.length(), false);
    }
    CorruptionUtils.corruptFile(random(), FileSystemUtils.files(tempDir, (p) -> (p.getFileName().toString().equals("write.lock") || p.getFileName().toString().startsWith("extra")) == false));
    Store targetStore = newStore(createTempDir(), false);
    MultiFileWriter multiFileWriter = new MultiFileWriter(targetStore, luceneIndex, "", logger, () -> {
    });
    RecoveryTargetHandler target = new TestRecoveryTargetHandler() {

        @Override
        public void writeFileChunk(StoreFileMetadata md, long position, BytesReference content, boolean lastChunk, int totalTranslogOps, ActionListener<Void> listener) {
            ActionListener.completeWith(listener, () -> {
                multiFileWriter.writeFileChunk(md, position, content, lastChunk);
                return null;
            });
        }
    };
    RecoverySourceHandler handler = new RecoverySourceHandler(null, new AsyncRecoveryTarget(target, recoveryExecutor), threadPool, request, Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 8), between(1, 8)) {

        @Override
        protected void failEngine(IOException cause) {
            assertFalse(failedEngine.get());
            failedEngine.set(true);
        }
    };
    SetOnce<Exception> sendFilesError = new SetOnce<>();
    CountDownLatch latch = new CountDownLatch(1);
    handler.sendFiles(store, metas.toArray(new StoreFileMetadata[0]), () -> 0, new LatchedActionListener<>(ActionListener.wrap(r -> sendFilesError.set(null), e -> sendFilesError.set(e)), latch));
    latch.await();
    assertThat(sendFilesError.get(), instanceOf(IOException.class));
    assertNotNull(ExceptionsHelper.unwrapCorruption(sendFilesError.get()));
    assertTrue(failedEngine.get());
    // ensure all chunk requests have been completed; otherwise some files on the target are left open.
    IOUtils.close(() -> terminate(threadPool), () -> threadPool = null);
    IOUtils.close(store, multiFileWriter, targetStore);
}
Also used : SeqNoStats(org.opensearch.index.seqno.SeqNoStats) SequenceNumbers(org.opensearch.index.seqno.SequenceNumbers) Arrays(java.util.Arrays) Term(org.apache.lucene.index.Term) TestThreadPool(org.opensearch.threadpool.TestThreadPool) RecoveryEngineException(org.opensearch.index.engine.RecoveryEngineException) Version(org.opensearch.Version) FileSystemUtils(org.opensearch.common.io.FileSystemUtils) BaseDirectoryWrapper(org.apache.lucene.tests.store.BaseDirectoryWrapper) Document(org.apache.lucene.document.Document) LatchedActionListener(org.opensearch.action.LatchedActionListener) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) Map(java.util.Map) Mockito.doAnswer(org.mockito.Mockito.doAnswer) ActionListener(org.opensearch.action.ActionListener) IOContext(org.apache.lucene.store.IOContext) Path(java.nio.file.Path) NumericDocValuesField(org.apache.lucene.document.NumericDocValuesField) TimeValue(org.opensearch.common.unit.TimeValue) ExceptionsHelper(org.opensearch.ExceptionsHelper) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) ReplicationTracker(org.opensearch.index.seqno.ReplicationTracker) StandardCharsets(java.nio.charset.StandardCharsets) Engine(org.opensearch.index.engine.Engine) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) CountDownLatch(java.util.concurrent.CountDownLatch) Randomness(org.opensearch.common.Randomness) BytesArray(org.opensearch.common.bytes.BytesArray) StepListener(org.opensearch.action.StepListener) XContentType(org.opensearch.common.xcontent.XContentType) Matchers.containsString(org.hamcrest.Matchers.containsString) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Mockito.mock(org.mockito.Mockito.mock) IndexCommit(org.apache.lucene.index.IndexCommit) CancellableThreads(org.opensearch.common.util.CancellableThreads) IndexShardState(org.opensearch.index.shard.IndexShardState) ThreadPool(org.opensearch.threadpool.ThreadPool) Releasable(org.opensearch.common.lease.Releasable) ArrayList(java.util.ArrayList) Numbers(org.opensearch.common.Numbers) VersionUtils(org.opensearch.test.VersionUtils) Matchers.hasSize(org.hamcrest.Matchers.hasSize) ParsedDocument(org.opensearch.index.mapper.ParsedDocument) CorruptionUtils(org.opensearch.test.CorruptionUtils) Mockito.anyString(org.mockito.Mockito.anyString) Before(org.junit.Before) ParseContext(org.opensearch.index.mapper.ParseContext) Versions(org.opensearch.common.lucene.uid.Versions) SetOnce(org.apache.lucene.util.SetOnce) Executor(java.util.concurrent.Executor) IOException(java.io.IOException) IndexShardRelocatedException(org.opensearch.index.shard.IndexShardRelocatedException) AtomicLong(java.util.concurrent.atomic.AtomicLong) RetentionLeases(org.opensearch.index.seqno.RetentionLeases) CRC32(java.util.zip.CRC32) TextField(org.apache.lucene.document.TextField) SeqNoFieldMapper(org.opensearch.index.mapper.SeqNoFieldMapper) IdFieldMapper(org.opensearch.index.mapper.IdFieldMapper) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Mockito.anyBoolean(org.mockito.Mockito.anyBoolean) Directory(org.apache.lucene.store.Directory) After(org.junit.After) DummyShardLock(org.opensearch.test.DummyShardLock) SegmentsStats(org.opensearch.index.engine.SegmentsStats) ReplicationLuceneIndex(org.opensearch.indices.replication.common.ReplicationLuceneIndex) DirectoryReader(org.apache.lucene.index.DirectoryReader) OpenSearchTestCase(org.opensearch.test.OpenSearchTestCase) Store(org.opensearch.index.store.Store) Collectors(java.util.stream.Collectors) GatedCloseable(org.opensearch.common.concurrent.GatedCloseable) List(java.util.List) RandomIndexWriter(org.apache.lucene.tests.index.RandomIndexWriter) Matchers.equalTo(org.hamcrest.Matchers.equalTo) IndexSettings(org.opensearch.index.IndexSettings) Queue(java.util.Queue) Mockito.any(org.mockito.Mockito.any) IndexReader(org.apache.lucene.index.IndexReader) Uid(org.opensearch.index.mapper.Uid) IndexSettingsModule(org.opensearch.test.IndexSettingsModule) BytesReference(org.opensearch.common.bytes.BytesReference) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) StringField(org.apache.lucene.document.StringField) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) IndexOutputOutputStream(org.opensearch.common.lucene.store.IndexOutputOutputStream) HashSet(java.util.HashSet) IndexShard(org.opensearch.index.shard.IndexShard) Translog(org.opensearch.index.translog.Translog) UUIDs(org.opensearch.common.UUIDs) ClusterSettings(org.opensearch.common.settings.ClusterSettings) StoreFileMetadata(org.opensearch.index.store.StoreFileMetadata) IntSupplier(java.util.function.IntSupplier) RetentionLease(org.opensearch.index.seqno.RetentionLease) OutputStream(java.io.OutputStream) Collections.emptyMap(java.util.Collections.emptyMap) Iterator(java.util.Iterator) Collections.emptySet(java.util.Collections.emptySet) Mockito.when(org.mockito.Mockito.when) IOUtils(org.opensearch.core.internal.io.IOUtils) ShardId(org.opensearch.index.shard.ShardId) FixedExecutorBuilder(org.opensearch.threadpool.FixedExecutorBuilder) Field(org.apache.lucene.document.Field) Comparator(java.util.Comparator) Collections(java.util.Collections) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Store(org.opensearch.index.store.Store) StoreFileMetadata(org.opensearch.index.store.StoreFileMetadata) Document(org.apache.lucene.document.Document) ParsedDocument(org.opensearch.index.mapper.ParsedDocument) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings) ClusterSettings(org.opensearch.common.settings.ClusterSettings) Directory(org.apache.lucene.store.Directory) Path(java.nio.file.Path) BytesReference(org.opensearch.common.bytes.BytesReference) SetOnce(org.apache.lucene.util.SetOnce) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) RecoveryEngineException(org.opensearch.index.engine.RecoveryEngineException) IOException(java.io.IOException) IndexShardRelocatedException(org.opensearch.index.shard.IndexShardRelocatedException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) ReplicationLuceneIndex(org.opensearch.indices.replication.common.ReplicationLuceneIndex) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LatchedActionListener(org.opensearch.action.LatchedActionListener) ActionListener(org.opensearch.action.ActionListener) StringField(org.apache.lucene.document.StringField) RandomIndexWriter(org.apache.lucene.tests.index.RandomIndexWriter)

Aggregations

ReplicationLuceneIndex (org.opensearch.indices.replication.common.ReplicationLuceneIndex)13 Directory (org.apache.lucene.store.Directory)5 ArrayList (java.util.ArrayList)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 StringField (org.apache.lucene.document.StringField)4 IOException (java.io.IOException)3 DirectoryReader (org.apache.lucene.index.DirectoryReader)3 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)3 Store (org.opensearch.index.store.Store)3 RecoveryState (org.opensearch.indices.recovery.RecoveryState)3 Path (java.nio.file.Path)2 Arrays (java.util.Arrays)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)2 Document (org.apache.lucene.document.Document)2 Field (org.apache.lucene.document.Field)2 IndexReader (org.apache.lucene.index.IndexReader)2 SegmentInfos (org.apache.lucene.index.SegmentInfos)2