Search in sources :

Example 31 with IndexCommit

use of org.apache.lucene.index.IndexCommit in project elasticsearch by elastic.

the class IndexShard method snapshotStoreMetadata.

/**
     * gets a {@link Store.MetadataSnapshot} for the current directory. This method is safe to call in all lifecycle of the index shard,
     * without having to worry about the current state of the engine and concurrent flushes.
     *
     * @throws org.apache.lucene.index.IndexNotFoundException     if no index is found in the current directory
     * @throws CorruptIndexException      if the lucene index is corrupted. This can be caused by a checksum mismatch or an
     *                                    unexpected exception when opening the index reading the segments file.
     * @throws IndexFormatTooOldException if the lucene index is too old to be opened.
     * @throws IndexFormatTooNewException if the lucene index is too new to be opened.
     * @throws FileNotFoundException      if one or more files referenced by a commit are not present.
     * @throws NoSuchFileException        if one or more files referenced by a commit are not present.
     */
public Store.MetadataSnapshot snapshotStoreMetadata() throws IOException {
    IndexCommit indexCommit = null;
    store.incRef();
    try {
        synchronized (mutex) {
            // if the engine is not running, we can access the store directly, but we need to make sure no one starts
            // the engine on us. If the engine is running, we can get a snapshot via the deletion policy which is initialized.
            // That can be done out of mutex, since the engine can be closed half way.
            Engine engine = getEngineOrNull();
            if (engine == null) {
                try (Lock ignored = store.directory().obtainLock(IndexWriter.WRITE_LOCK_NAME)) {
                    return store.getMetadata(null);
                }
            }
        }
        indexCommit = deletionPolicy.snapshot();
        return store.getMetadata(indexCommit);
    } finally {
        store.decRef();
        if (indexCommit != null) {
            deletionPolicy.release(indexCommit);
        }
    }
}
Also used : IndexCommit(org.apache.lucene.index.IndexCommit) Engine(org.elasticsearch.index.engine.Engine) Lock(org.apache.lucene.store.Lock)

Example 32 with IndexCommit

use of org.apache.lucene.index.IndexCommit in project elasticsearch by elastic.

the class InternalEngineTests method testConcurrentWritesAndCommits.

// this test writes documents to the engine while concurrently flushing/commit
// and ensuring that the commit points contain the correct sequence number data
public void testConcurrentWritesAndCommits() throws Exception {
    try (Store store = createStore();
        InternalEngine engine = new InternalEngine(config(defaultSettings, store, createTempDir(), newMergePolicy(), new SnapshotDeletionPolicy(NoDeletionPolicy.INSTANCE), IndexRequest.UNSET_AUTO_GENERATED_TIMESTAMP, null))) {
        final int numIndexingThreads = scaledRandomIntBetween(3, 6);
        final int numDocsPerThread = randomIntBetween(500, 1000);
        final CyclicBarrier barrier = new CyclicBarrier(numIndexingThreads + 1);
        final List<Thread> indexingThreads = new ArrayList<>();
        // create N indexing threads to index documents simultaneously
        for (int threadNum = 0; threadNum < numIndexingThreads; threadNum++) {
            final int threadIdx = threadNum;
            Thread indexingThread = new Thread(() -> {
                try {
                    // wait for all threads to start at the same time
                    barrier.await();
                    // index random number of docs
                    for (int i = 0; i < numDocsPerThread; i++) {
                        final String id = "thread" + threadIdx + "#" + i;
                        ParsedDocument doc = testParsedDocument(id, "test", null, testDocument(), B_1, null);
                        engine.index(indexForDoc(doc));
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
            indexingThreads.add(indexingThread);
        }
        // start the indexing threads
        for (Thread thread : indexingThreads) {
            thread.start();
        }
        // wait for indexing threads to all be ready to start
        barrier.await();
        // create random commit points
        boolean doneIndexing;
        do {
            doneIndexing = indexingThreads.stream().filter(Thread::isAlive).count() == 0;
        //engine.flush(); // flush and commit
        } while (doneIndexing == false);
        // now, verify all the commits have the correct docs according to the user commit data
        long prevLocalCheckpoint = SequenceNumbersService.NO_OPS_PERFORMED;
        long prevMaxSeqNo = SequenceNumbersService.NO_OPS_PERFORMED;
        for (IndexCommit commit : DirectoryReader.listCommits(store.directory())) {
            Map<String, String> userData = commit.getUserData();
            long localCheckpoint = userData.containsKey(SequenceNumbers.LOCAL_CHECKPOINT_KEY) ? Long.parseLong(userData.get(SequenceNumbers.LOCAL_CHECKPOINT_KEY)) : SequenceNumbersService.NO_OPS_PERFORMED;
            long maxSeqNo = userData.containsKey(SequenceNumbers.MAX_SEQ_NO) ? Long.parseLong(userData.get(SequenceNumbers.MAX_SEQ_NO)) : SequenceNumbersService.UNASSIGNED_SEQ_NO;
            // local checkpoint and max seq no shouldn't go backwards
            assertThat(localCheckpoint, greaterThanOrEqualTo(prevLocalCheckpoint));
            assertThat(maxSeqNo, greaterThanOrEqualTo(prevMaxSeqNo));
            try (IndexReader reader = DirectoryReader.open(commit)) {
                FieldStats stats = SeqNoFieldMapper.SeqNoDefaults.FIELD_TYPE.stats(reader);
                final long highestSeqNo;
                if (stats != null) {
                    highestSeqNo = (long) stats.getMaxValue();
                } else {
                    highestSeqNo = SequenceNumbersService.NO_OPS_PERFORMED;
                }
                // make sure localCheckpoint <= highest seq no found <= maxSeqNo
                assertThat(highestSeqNo, greaterThanOrEqualTo(localCheckpoint));
                assertThat(highestSeqNo, lessThanOrEqualTo(maxSeqNo));
                // make sure all sequence numbers up to and including the local checkpoint are in the index
                FixedBitSet seqNosBitSet = getSeqNosSet(reader, highestSeqNo);
                for (int i = 0; i <= localCheckpoint; i++) {
                    assertTrue("local checkpoint [" + localCheckpoint + "], _seq_no [" + i + "] should be indexed", seqNosBitSet.get(i));
                }
            }
            prevLocalCheckpoint = localCheckpoint;
            prevMaxSeqNo = maxSeqNo;
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Store(org.elasticsearch.index.store.Store) Matchers.containsString(org.hamcrest.Matchers.containsString) SnapshotDeletionPolicy(org.apache.lucene.index.SnapshotDeletionPolicy) LongPoint(org.apache.lucene.document.LongPoint) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) BrokenBarrierException(java.util.concurrent.BrokenBarrierException) ElasticsearchException(org.elasticsearch.ElasticsearchException) IndexCommit(org.apache.lucene.index.IndexCommit) CyclicBarrier(java.util.concurrent.CyclicBarrier) FieldStats(org.elasticsearch.action.fieldstats.FieldStats) ParsedDocument(org.elasticsearch.index.mapper.ParsedDocument) FixedBitSet(org.apache.lucene.util.FixedBitSet) IndexReader(org.apache.lucene.index.IndexReader)

Example 33 with IndexCommit

use of org.apache.lucene.index.IndexCommit in project elasticsearch by elastic.

the class RecoverySourceHandlerTests method testThrowExceptionOnPrimaryRelocatedBeforePhase1Completed.

public void testThrowExceptionOnPrimaryRelocatedBeforePhase1Completed() throws IOException {
    final RecoverySettings recoverySettings = new RecoverySettings(Settings.EMPTY, service);
    final boolean attemptSequenceNumberBasedRecovery = randomBoolean();
    final boolean isTranslogReadyForSequenceNumberBasedRecovery = attemptSequenceNumberBasedRecovery && randomBoolean();
    final StartRecoveryRequest request = new StartRecoveryRequest(shardId, new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT), new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT), null, false, randomNonNegativeLong(), attemptSequenceNumberBasedRecovery ? randomNonNegativeLong() : SequenceNumbersService.UNASSIGNED_SEQ_NO);
    final IndexShard shard = mock(IndexShard.class);
    when(shard.seqNoStats()).thenReturn(mock(SeqNoStats.class));
    when(shard.segmentStats(anyBoolean())).thenReturn(mock(SegmentsStats.class));
    final Translog.View translogView = mock(Translog.View.class);
    when(shard.acquireTranslogView()).thenReturn(translogView);
    when(shard.state()).thenReturn(IndexShardState.RELOCATED);
    final AtomicBoolean phase1Called = new AtomicBoolean();
    final AtomicBoolean prepareTargetForTranslogCalled = new AtomicBoolean();
    final AtomicBoolean phase2Called = new AtomicBoolean();
    final RecoverySourceHandler handler = new RecoverySourceHandler(shard, mock(RecoveryTargetHandler.class), request, () -> 0L, e -> () -> {
    }, recoverySettings.getChunkSize().bytesAsInt(), Settings.EMPTY) {

        @Override
        boolean isTranslogReadyForSequenceNumberBasedRecovery(final Translog.View translogView) {
            return isTranslogReadyForSequenceNumberBasedRecovery;
        }

        @Override
        public void phase1(final IndexCommit snapshot, final Translog.View translogView) {
            phase1Called.set(true);
        }

        @Override
        void prepareTargetForTranslog(final int totalTranslogOps, final long maxUnsafeAutoIdTimestamp) throws IOException {
            prepareTargetForTranslogCalled.set(true);
        }

        @Override
        void phase2(long startingSeqNo, Translog.Snapshot snapshot) throws IOException {
            phase2Called.set(true);
        }
    };
    expectThrows(IndexShardRelocatedException.class, handler::recoverToTarget);
    // phase1 should only be attempted if we are not doing a sequence-number-based recovery
    assertThat(phase1Called.get(), equalTo(!isTranslogReadyForSequenceNumberBasedRecovery));
    assertTrue(prepareTargetForTranslogCalled.get());
    assertFalse(phase2Called.get());
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) IndexShard(org.elasticsearch.index.shard.IndexShard) SegmentsStats(org.elasticsearch.index.engine.SegmentsStats) IndexCommit(org.apache.lucene.index.IndexCommit) Translog(org.elasticsearch.index.translog.Translog) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SeqNoStats(org.elasticsearch.index.seqno.SeqNoStats)

Example 34 with IndexCommit

use of org.apache.lucene.index.IndexCommit in project elasticsearch by elastic.

the class RecoverySourceHandlerTests method testWaitForClusterStateOnPrimaryRelocation.

public void testWaitForClusterStateOnPrimaryRelocation() throws IOException, InterruptedException {
    final RecoverySettings recoverySettings = new RecoverySettings(Settings.EMPTY, service);
    final boolean attemptSequenceNumberBasedRecovery = randomBoolean();
    final boolean isTranslogReadyForSequenceNumberBasedRecovery = attemptSequenceNumberBasedRecovery && randomBoolean();
    final StartRecoveryRequest request = new StartRecoveryRequest(shardId, new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT), new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT), null, true, randomNonNegativeLong(), attemptSequenceNumberBasedRecovery ? randomNonNegativeLong() : SequenceNumbersService.UNASSIGNED_SEQ_NO);
    final AtomicBoolean phase1Called = new AtomicBoolean();
    final AtomicBoolean prepareTargetForTranslogCalled = new AtomicBoolean();
    final AtomicBoolean phase2Called = new AtomicBoolean();
    final AtomicBoolean ensureClusterStateVersionCalled = new AtomicBoolean();
    final AtomicBoolean recoveriesDelayed = new AtomicBoolean();
    final AtomicBoolean relocated = new AtomicBoolean();
    final IndexShard shard = mock(IndexShard.class);
    when(shard.seqNoStats()).thenReturn(mock(SeqNoStats.class));
    when(shard.segmentStats(anyBoolean())).thenReturn(mock(SegmentsStats.class));
    final Translog.View translogView = mock(Translog.View.class);
    when(shard.acquireTranslogView()).thenReturn(translogView);
    when(shard.state()).then(i -> relocated.get() ? IndexShardState.RELOCATED : IndexShardState.STARTED);
    doAnswer(i -> {
        relocated.set(true);
        assertTrue(recoveriesDelayed.get());
        return null;
    }).when(shard).relocated(any(String.class));
    final Supplier<Long> currentClusterStateVersionSupplier = () -> {
        assertFalse(ensureClusterStateVersionCalled.get());
        assertTrue(recoveriesDelayed.get());
        ensureClusterStateVersionCalled.set(true);
        return 0L;
    };
    final Function<String, Releasable> delayNewRecoveries = s -> {
        assertThat(phase1Called.get(), equalTo(!isTranslogReadyForSequenceNumberBasedRecovery));
        assertTrue(prepareTargetForTranslogCalled.get());
        assertTrue(phase2Called.get());
        assertFalse(recoveriesDelayed.get());
        recoveriesDelayed.set(true);
        return () -> {
            assertTrue(recoveriesDelayed.get());
            recoveriesDelayed.set(false);
        };
    };
    final RecoverySourceHandler handler = new RecoverySourceHandler(shard, mock(RecoveryTargetHandler.class), request, currentClusterStateVersionSupplier, delayNewRecoveries, recoverySettings.getChunkSize().bytesAsInt(), Settings.EMPTY) {

        @Override
        boolean isTranslogReadyForSequenceNumberBasedRecovery(final Translog.View translogView) {
            return isTranslogReadyForSequenceNumberBasedRecovery;
        }

        @Override
        public void phase1(final IndexCommit snapshot, final Translog.View translogView) {
            phase1Called.set(true);
        }

        @Override
        void prepareTargetForTranslog(final int totalTranslogOps, final long maxUnsafeAutoIdTimestamp) throws IOException {
            prepareTargetForTranslogCalled.set(true);
        }

        @Override
        void phase2(long startingSeqNo, Translog.Snapshot snapshot) throws IOException {
            phase2Called.set(true);
        }
    };
    handler.recoverToTarget();
    assertTrue(ensureClusterStateVersionCalled.get());
    // phase1 should only be attempted if we are not doing a sequence-number-based recovery
    assertThat(phase1Called.get(), equalTo(!isTranslogReadyForSequenceNumberBasedRecovery));
    assertTrue(prepareTargetForTranslogCalled.get());
    assertTrue(phase2Called.get());
    assertTrue(relocated.get());
    assertFalse(recoveriesDelayed.get());
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) Versions(org.elasticsearch.common.lucene.uid.Versions) Arrays(java.util.Arrays) IndexSettingsModule(org.elasticsearch.test.IndexSettingsModule) Term(org.apache.lucene.index.Term) ParseContext(org.elasticsearch.index.mapper.ParseContext) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) SeqNoStats(org.elasticsearch.index.seqno.SeqNoStats) Document(org.apache.lucene.document.Document) Matchers.anyBoolean(org.mockito.Matchers.anyBoolean) Settings(org.elasticsearch.common.settings.Settings) Directory(org.apache.lucene.store.Directory) Mockito.doAnswer(org.mockito.Mockito.doAnswer) UidFieldMapper(org.elasticsearch.index.mapper.UidFieldMapper) IOContext(org.apache.lucene.store.IOContext) Path(java.nio.file.Path) Releasable(org.elasticsearch.common.lease.Releasable) NumericDocValuesField(org.apache.lucene.document.NumericDocValuesField) DirectoryReader(org.apache.lucene.index.DirectoryReader) BytesReference(org.elasticsearch.common.bytes.BytesReference) Engine(org.elasticsearch.index.engine.Engine) Matchers.any(org.mockito.Matchers.any) SeqNoFieldMapper(org.elasticsearch.index.mapper.SeqNoFieldMapper) List(java.util.List) Version(org.elasticsearch.Version) IndexMetaData(org.elasticsearch.cluster.metadata.IndexMetaData) Matchers.equalTo(org.hamcrest.Matchers.equalTo) IndexOutputOutputStream(org.elasticsearch.common.lucene.store.IndexOutputOutputStream) IndexReader(org.apache.lucene.index.IndexReader) Mockito.mock(org.mockito.Mockito.mock) IndexCommit(org.apache.lucene.index.IndexCommit) XContentType(org.elasticsearch.common.xcontent.XContentType) StringField(org.apache.lucene.document.StringField) IndexShardRelocatedException(org.elasticsearch.index.shard.IndexShardRelocatedException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SegmentsStats(org.elasticsearch.index.engine.SegmentsStats) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) BytesArray(org.elasticsearch.common.bytes.BytesArray) BaseDirectoryWrapper(org.apache.lucene.store.BaseDirectoryWrapper) StoreFileMetaData(org.elasticsearch.index.store.StoreFileMetaData) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) SequenceNumbersService(org.elasticsearch.index.seqno.SequenceNumbersService) Store(org.elasticsearch.index.store.Store) IndexSettings(org.elasticsearch.index.IndexSettings) Mapping(org.elasticsearch.index.mapper.Mapping) ESTestCase(org.elasticsearch.test.ESTestCase) Collections.emptyMap(java.util.Collections.emptyMap) FileSystemUtils(org.elasticsearch.common.io.FileSystemUtils) IndexShardState(org.elasticsearch.index.shard.IndexShardState) CorruptionUtils(org.elasticsearch.test.CorruptionUtils) Uid(org.elasticsearch.index.mapper.Uid) Collections.emptySet(java.util.Collections.emptySet) IndexShard(org.elasticsearch.index.shard.IndexShard) IOUtils(org.apache.lucene.util.IOUtils) IOException(java.io.IOException) ParsedDocument(org.elasticsearch.index.mapper.ParsedDocument) Mockito.when(org.mockito.Mockito.when) DirectoryService(org.elasticsearch.index.store.DirectoryService) ExceptionsHelper(org.elasticsearch.ExceptionsHelper) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) Field(org.apache.lucene.document.Field) Translog(org.elasticsearch.index.translog.Translog) TextField(org.apache.lucene.document.TextField) DummyShardLock(org.elasticsearch.test.DummyShardLock) RandomIndexWriter(org.apache.lucene.index.RandomIndexWriter) Collections(java.util.Collections) DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) IndexShard(org.elasticsearch.index.shard.IndexShard) SegmentsStats(org.elasticsearch.index.engine.SegmentsStats) IndexCommit(org.apache.lucene.index.IndexCommit) Translog(org.elasticsearch.index.translog.Translog) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SeqNoStats(org.elasticsearch.index.seqno.SeqNoStats) Releasable(org.elasticsearch.common.lease.Releasable)

Example 35 with IndexCommit

use of org.apache.lucene.index.IndexCommit in project lucene-solr by apache.

the class SolrDeletionPolicy method updateCommits.

private void updateCommits(List<? extends IndexCommit> commits) {
    synchronized (this) {
        long maxCommitAgeTimeStamp = -1L;
        IndexCommit newest = commits.get(commits.size() - 1);
        log.debug("newest commit generation = " + newest.getGeneration());
        int singleSegKept = (newest.getSegmentCount() == 1) ? 1 : 0;
        int totalKept = 1;
        // work our way from newest to oldest, skipping the first since we always want to keep it.
        for (int i = commits.size() - 2; i >= 0; i--) {
            IndexCommit commit = commits.get(i);
            // delete anything too old, regardless of other policies
            try {
                if (maxCommitAge != null) {
                    if (maxCommitAgeTimeStamp == -1) {
                        DateMathParser dmp = new DateMathParser(DateMathParser.UTC);
                        maxCommitAgeTimeStamp = dmp.parseMath(maxCommitAge).getTime();
                    }
                    if (IndexDeletionPolicyWrapper.getCommitTimestamp(commit) < maxCommitAgeTimeStamp) {
                        commit.delete();
                        continue;
                    }
                }
            } catch (Exception e) {
                log.warn("Exception while checking commit point's age for deletion", e);
            }
            if (singleSegKept < maxOptimizedCommitsToKeep && commit.getSegmentCount() == 1) {
                totalKept++;
                singleSegKept++;
                continue;
            }
            if (totalKept < maxCommitsToKeep) {
                totalKept++;
                continue;
            }
            commit.delete();
        }
    }
// end synchronized
}
Also used : DateMathParser(org.apache.solr.util.DateMathParser) IndexCommit(org.apache.lucene.index.IndexCommit) IOException(java.io.IOException)

Aggregations

IndexCommit (org.apache.lucene.index.IndexCommit)60 IOException (java.io.IOException)24 ArrayList (java.util.ArrayList)22 AtomicLong (java.util.concurrent.atomic.AtomicLong)11 Directory (org.apache.lucene.store.Directory)11 Test (org.junit.Test)10 IndexWriter (org.apache.lucene.index.IndexWriter)9 Store (org.elasticsearch.index.store.Store)9 Translog (org.elasticsearch.index.translog.Translog)8 List (java.util.List)7 Map (java.util.Map)7 SolrException (org.apache.solr.common.SolrException)7 NoSuchFileException (java.nio.file.NoSuchFileException)6 HashMap (java.util.HashMap)6 LongPoint (org.apache.lucene.document.LongPoint)6 DirectoryReader (org.apache.lucene.index.DirectoryReader)6 IndexReader (org.apache.lucene.index.IndexReader)6 UncheckedIOException (java.io.UncheckedIOException)5 Collections (java.util.Collections)5 IndexSettings (org.elasticsearch.index.IndexSettings)5