Search in sources :

Example 1 with InternalEngineFactory

use of org.opensearch.index.engine.InternalEngineFactory in project OpenSearch by opensearch-project.

the class RecoveryDuringReplicationTests method testDoNotWaitForPendingSeqNo.

public void testDoNotWaitForPendingSeqNo() throws Exception {
    IndexMetadata metadata = buildIndexMetadata(1);
    final int pendingDocs = randomIntBetween(1, 5);
    final BlockingEngineFactory primaryEngineFactory = new BlockingEngineFactory();
    try (ReplicationGroup shards = new ReplicationGroup(metadata) {

        @Override
        protected EngineFactory getEngineFactory(ShardRouting routing) {
            if (routing.primary()) {
                return primaryEngineFactory;
            } else {
                return new InternalEngineFactory();
            }
        }
    }) {
        shards.startAll();
        int docs = shards.indexDocs(randomIntBetween(1, 10));
        // simulate a background global checkpoint sync at which point we expect the global checkpoint to advance on the replicas
        shards.syncGlobalCheckpoint();
        IndexShard replica = shards.getReplicas().get(0);
        shards.removeReplica(replica);
        closeShards(replica);
        docs += pendingDocs;
        primaryEngineFactory.latchIndexers(pendingDocs);
        CountDownLatch pendingDocsDone = new CountDownLatch(pendingDocs);
        for (int i = 0; i < pendingDocs; i++) {
            final String id = "pending_" + i;
            threadPool.generic().submit(() -> {
                try {
                    shards.index(new IndexRequest(index.getName()).id(id).source("{}", XContentType.JSON));
                } catch (Exception e) {
                    throw new AssertionError(e);
                } finally {
                    pendingDocsDone.countDown();
                }
            });
        }
        // wait for the pending ops to "hang"
        primaryEngineFactory.awaitIndexersLatch();
        primaryEngineFactory.allowIndexing();
        // index some more
        docs += shards.indexDocs(randomInt(5));
        IndexShard newReplica = shards.addReplicaWithExistingPath(replica.shardPath(), replica.routingEntry().currentNodeId());
        CountDownLatch recoveryStart = new CountDownLatch(1);
        AtomicBoolean recoveryDone = new AtomicBoolean(false);
        final Future<Void> recoveryFuture = shards.asyncRecoverReplica(newReplica, (indexShard, node) -> {
            recoveryStart.countDown();
            return new RecoveryTarget(indexShard, node, recoveryListener) {

                @Override
                public void finalizeRecovery(long globalCheckpoint, long trimAboveSeqNo, ActionListener<Void> listener) {
                    recoveryDone.set(true);
                    super.finalizeRecovery(globalCheckpoint, trimAboveSeqNo, listener);
                }
            };
        });
        recoveryStart.await();
        // index some more
        final int indexedDuringRecovery = shards.indexDocs(randomInt(5));
        docs += indexedDuringRecovery;
        assertBusy(() -> assertTrue("recovery should not wait for on pending docs", recoveryDone.get()));
        primaryEngineFactory.releaseLatchedIndexers();
        pendingDocsDone.await();
        // now recovery can finish
        recoveryFuture.get();
        assertThat(newReplica.recoveryState().getIndex().fileDetails(), empty());
        shards.assertAllEqual(docs);
    } finally {
        primaryEngineFactory.close();
    }
}
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) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ActionListener(org.opensearch.action.ActionListener) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ShardRouting(org.opensearch.cluster.routing.ShardRouting)

Example 2 with InternalEngineFactory

use of org.opensearch.index.engine.InternalEngineFactory in project OpenSearch by opensearch-project.

the class IndexShardTests method testClosedIndicesSkipSyncGlobalCheckpoint.

public void testClosedIndicesSkipSyncGlobalCheckpoint() throws Exception {
    ShardId shardId = new ShardId("index", "_na_", 0);
    IndexMetadata.Builder indexMetadata = IndexMetadata.builder("index").settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT).put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 2)).state(IndexMetadata.State.CLOSE).primaryTerm(0, 1);
    ShardRouting shardRouting = TestShardRouting.newShardRouting(shardId, randomAlphaOfLength(8), true, ShardRoutingState.INITIALIZING, RecoverySource.EmptyStoreRecoverySource.INSTANCE);
    AtomicBoolean synced = new AtomicBoolean();
    IndexShard primaryShard = newShard(shardRouting, indexMetadata.build(), null, new InternalEngineFactory(), () -> synced.set(true), RetentionLeaseSyncer.EMPTY);
    recoverShardFromStore(primaryShard);
    IndexShard replicaShard = newShard(shardId, false);
    recoverReplica(replicaShard, primaryShard, true);
    int numDocs = between(1, 10);
    for (int i = 0; i < numDocs; i++) {
        indexDoc(primaryShard, "_doc", Integer.toString(i));
    }
    assertThat(primaryShard.getLocalCheckpoint(), equalTo(numDocs - 1L));
    primaryShard.updateLocalCheckpointForShard(replicaShard.shardRouting.allocationId().getId(), primaryShard.getLocalCheckpoint());
    long globalCheckpointOnReplica = randomLongBetween(SequenceNumbers.NO_OPS_PERFORMED, primaryShard.getLocalCheckpoint());
    primaryShard.updateGlobalCheckpointForShard(replicaShard.shardRouting.allocationId().getId(), globalCheckpointOnReplica);
    primaryShard.maybeSyncGlobalCheckpoint("test");
    assertFalse("closed indices should skip global checkpoint sync", synced.get());
    closeShards(primaryShard, replicaShard);
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) TestShardRouting.newShardRouting(org.opensearch.cluster.routing.TestShardRouting.newShardRouting) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting)

Example 3 with InternalEngineFactory

use of org.opensearch.index.engine.InternalEngineFactory in project OpenSearch by opensearch-project.

the class IndexShardTests method testDoNotTrimCommitsWhenOpenReadOnlyEngine.

public void testDoNotTrimCommitsWhenOpenReadOnlyEngine() throws Exception {
    final IndexShard shard = newStartedShard(false, Settings.EMPTY, new InternalEngineFactory());
    long numDocs = randomLongBetween(1, 20);
    long seqNo = 0;
    for (long i = 0; i < numDocs; i++) {
        if (rarely()) {
            // create gaps in sequence numbers
            seqNo++;
        }
        shard.applyIndexOperationOnReplica(seqNo, shard.getOperationPrimaryTerm(), 1, IndexRequest.UNSET_AUTO_GENERATED_TIMESTAMP, false, new SourceToParse(shard.shardId.getIndexName(), "_doc", Long.toString(i), new BytesArray("{}"), XContentType.JSON));
        shard.updateGlobalCheckpointOnReplica(shard.getLocalCheckpoint(), "test");
        if (randomInt(100) < 10) {
            shard.flush(new FlushRequest());
        }
        seqNo++;
    }
    shard.flush(new FlushRequest());
    assertThat(shard.docStats().getCount(), equalTo(numDocs));
    final ShardRouting replicaRouting = shard.routingEntry();
    ShardRouting readonlyShardRouting = newShardRouting(replicaRouting.shardId(), replicaRouting.currentNodeId(), true, ShardRoutingState.INITIALIZING, RecoverySource.ExistingStoreRecoverySource.INSTANCE);
    final IndexShard readonlyShard = reinitShard(shard, readonlyShardRouting, shard.indexSettings.getIndexMetadata(), engineConfig -> new ReadOnlyEngine(engineConfig, null, null, true, Function.identity(), true) {

        @Override
        protected void ensureMaxSeqNoEqualsToGlobalCheckpoint(SeqNoStats seqNoStats) {
        // just like a following shard, we need to skip this check for now.
        }
    }, shard.getEngineConfigFactory());
    DiscoveryNode localNode = new DiscoveryNode("foo", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
    readonlyShard.markAsRecovering("store", new RecoveryState(readonlyShard.routingEntry(), localNode, null));
    recoverFromStore(readonlyShard);
    assertThat(readonlyShard.docStats().getCount(), equalTo(numDocs));
    closeShards(readonlyShard);
}
Also used : BytesArray(org.opensearch.common.bytes.BytesArray) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) SeqNoStats(org.opensearch.index.seqno.SeqNoStats) FlushRequest(org.opensearch.action.admin.indices.flush.FlushRequest) ReadOnlyEngine(org.opensearch.index.engine.ReadOnlyEngine) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) SourceToParse(org.opensearch.index.mapper.SourceToParse) TestShardRouting.newShardRouting(org.opensearch.cluster.routing.TestShardRouting.newShardRouting) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) RecoveryState(org.opensearch.indices.recovery.RecoveryState)

Example 4 with InternalEngineFactory

use of org.opensearch.index.engine.InternalEngineFactory in project OpenSearch by opensearch-project.

the class RemoveCorruptedShardDataCommandTests method setup.

@Before
public void setup() throws IOException {
    shardId = new ShardId("index0", UUIDs.randomBase64UUID(), 0);
    final String nodeId = randomAlphaOfLength(10);
    routing = TestShardRouting.newShardRouting(shardId, nodeId, true, ShardRoutingState.INITIALIZING, RecoverySource.EmptyStoreRecoverySource.INSTANCE);
    final Path dataDir = createTempDir();
    environment = TestEnvironment.newEnvironment(Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), dataDir).putList(Environment.PATH_DATA_SETTING.getKey(), dataDir.toAbsolutePath().toString()).build());
    // create same directory structure as prod does
    final Path path = NodeEnvironment.resolveNodePath(dataDir, 0);
    Files.createDirectories(path);
    dataPaths = new Path[] { path };
    final Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT).put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).put(MergePolicyConfig.INDEX_MERGE_ENABLED, false).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0).put(IndexMetadata.SETTING_INDEX_UUID, shardId.getIndex().getUUID()).build();
    final NodeEnvironment.NodePath nodePath = new NodeEnvironment.NodePath(path);
    shardPath = new ShardPath(false, nodePath.resolve(shardId), nodePath.resolve(shardId), shardId);
    final IndexMetadata.Builder metadata = IndexMetadata.builder(routing.getIndexName()).settings(settings).primaryTerm(0, randomIntBetween(1, 100)).putMapping("_doc", "{ \"properties\": {} }");
    indexMetadata = metadata.build();
    clusterState = ClusterState.builder(ClusterName.DEFAULT).metadata(Metadata.builder().put(indexMetadata, false).build()).build();
    try (NodeEnvironment.NodeLock lock = new NodeEnvironment.NodeLock(0, logger, environment, Files::exists)) {
        final Path[] dataPaths = Arrays.stream(lock.getNodePaths()).filter(Objects::nonNull).map(p -> p.path).toArray(Path[]::new);
        try (PersistedClusterStateService.Writer writer = new PersistedClusterStateService(dataPaths, nodeId, xContentRegistry(), BigArrays.NON_RECYCLING_INSTANCE, new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), () -> 0L).createWriter()) {
            writer.writeFullStateAndCommit(1L, clusterState);
        }
    }
    indexShard = newStartedShard(p -> newShard(routing, shardPath, indexMetadata, null, null, new InternalEngineFactory(), new EngineConfigFactory(new IndexSettings(indexMetadata, settings)), () -> {
    }, RetentionLeaseSyncer.EMPTY, EMPTY_EVENT_LISTENER), true);
    translogPath = shardPath.resolveTranslog();
    indexPath = shardPath.resolveIndex();
}
Also used : Path(java.nio.file.Path) EngineException(org.opensearch.index.engine.EngineException) Arrays(java.util.Arrays) TranslogCorruptedException(org.opensearch.index.translog.TranslogCorruptedException) Matchers.either(org.hamcrest.Matchers.either) MockTerminal(org.opensearch.cli.MockTerminal) Metadata(org.opensearch.cluster.metadata.Metadata) TRUNCATE_CLEAN_TRANSLOG_FLAG(org.opensearch.index.shard.RemoveCorruptedShardDataCommand.TRUNCATE_CLEAN_TRANSLOG_FLAG) CheckedFunction(org.opensearch.common.CheckedFunction) Version(org.opensearch.Version) OpenSearchException(org.opensearch.OpenSearchException) Matcher(java.util.regex.Matcher) OptionParser(joptsimple.OptionParser) DummyShardLock(org.opensearch.test.DummyShardLock) Path(java.nio.file.Path) OptionSet(joptsimple.OptionSet) NodeEnvironment(org.opensearch.env.NodeEnvironment) Matchers.allOf(org.hamcrest.Matchers.allOf) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) Store(org.opensearch.index.store.Store) Matchers.startsWith(org.hamcrest.Matchers.startsWith) Objects(java.util.Objects) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) EngineConfigFactory(org.opensearch.index.engine.EngineConfigFactory) Matchers.equalTo(org.hamcrest.Matchers.equalTo) IndexSettings(org.opensearch.index.IndexSettings) Matchers.is(org.hamcrest.Matchers.is) ShardRoutingHelper(org.opensearch.cluster.routing.ShardRoutingHelper) Pattern(java.util.regex.Pattern) BigArrays(org.opensearch.common.util.BigArrays) Matchers.containsString(org.hamcrest.Matchers.containsString) TestEnvironment(org.opensearch.env.TestEnvironment) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) RecoverySource(org.opensearch.cluster.routing.RecoverySource) BaseDirectoryWrapper(org.apache.lucene.store.BaseDirectoryWrapper) PersistedClusterStateService(org.opensearch.gateway.PersistedClusterStateService) ClusterState(org.opensearch.cluster.ClusterState) ShardRoutingState(org.opensearch.cluster.routing.ShardRoutingState) UUIDs(org.opensearch.common.UUIDs) ClusterSettings(org.opensearch.common.settings.ClusterSettings) CorruptionUtils(org.opensearch.test.CorruptionUtils) Before(org.junit.Before) Environment(org.opensearch.env.Environment) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) Terminal(org.opensearch.cli.Terminal) Files(java.nio.file.Files) TestTranslog(org.opensearch.index.translog.TestTranslog) IOException(java.io.IOException) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) ClusterName(org.opensearch.cluster.ClusterName) MergePolicyConfig(org.opensearch.index.MergePolicyConfig) RetentionLeaseSyncer(org.opensearch.index.seqno.RetentionLeaseSyncer) ClusterSettings(org.opensearch.common.settings.ClusterSettings) NodeEnvironment(org.opensearch.env.NodeEnvironment) IndexSettings(org.opensearch.index.IndexSettings) Matchers.containsString(org.hamcrest.Matchers.containsString) EngineConfigFactory(org.opensearch.index.engine.EngineConfigFactory) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) Objects(java.util.Objects) PersistedClusterStateService(org.opensearch.gateway.PersistedClusterStateService) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) Files(java.nio.file.Files) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings) ClusterSettings(org.opensearch.common.settings.ClusterSettings) Before(org.junit.Before)

Example 5 with InternalEngineFactory

use of org.opensearch.index.engine.InternalEngineFactory in project OpenSearch by opensearch-project.

the class IndexShardTests method testGlobalCheckpointSync.

public void testGlobalCheckpointSync() throws IOException {
    // create the primary shard with a callback that sets a boolean when the global checkpoint sync is invoked
    final ShardId shardId = new ShardId("index", "_na_", 0);
    final ShardRouting shardRouting = TestShardRouting.newShardRouting(shardId, randomAlphaOfLength(8), true, ShardRoutingState.INITIALIZING, RecoverySource.EmptyStoreRecoverySource.INSTANCE);
    final Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT).put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 2).put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1).build();
    final IndexMetadata.Builder indexMetadata = IndexMetadata.builder(shardRouting.getIndexName()).settings(settings).primaryTerm(0, 1);
    final AtomicBoolean synced = new AtomicBoolean();
    final IndexShard primaryShard = newShard(shardRouting, indexMetadata.build(), null, new InternalEngineFactory(), () -> synced.set(true), RetentionLeaseSyncer.EMPTY);
    // add a replica
    recoverShardFromStore(primaryShard);
    final IndexShard replicaShard = newShard(shardId, false);
    recoverReplica(replicaShard, primaryShard, true);
    final int maxSeqNo = randomIntBetween(0, 128);
    for (int i = 0; i <= maxSeqNo; i++) {
        EngineTestCase.generateNewSeqNo(primaryShard.getEngine());
    }
    final long checkpoint = rarely() ? maxSeqNo - scaledRandomIntBetween(0, maxSeqNo) : maxSeqNo;
    // set up local checkpoints on the shard copies
    primaryShard.updateLocalCheckpointForShard(shardRouting.allocationId().getId(), checkpoint);
    final int replicaLocalCheckpoint = randomIntBetween(0, Math.toIntExact(checkpoint));
    final String replicaAllocationId = replicaShard.routingEntry().allocationId().getId();
    primaryShard.updateLocalCheckpointForShard(replicaAllocationId, replicaLocalCheckpoint);
    // initialize the local knowledge on the primary of the persisted global checkpoint on the replica shard
    final int replicaGlobalCheckpoint = randomIntBetween(Math.toIntExact(SequenceNumbers.NO_OPS_PERFORMED), Math.toIntExact(primaryShard.getLastKnownGlobalCheckpoint()));
    primaryShard.updateGlobalCheckpointForShard(replicaAllocationId, replicaGlobalCheckpoint);
    // initialize the local knowledge on the primary of the persisted global checkpoint on the primary
    primaryShard.updateGlobalCheckpointForShard(shardRouting.allocationId().getId(), primaryShard.getLastKnownGlobalCheckpoint());
    // simulate a background maybe sync; it should only run if the knowledge on the replica of the global checkpoint lags the primary
    primaryShard.maybeSyncGlobalCheckpoint("test");
    assertThat(synced.get(), equalTo(maxSeqNo == primaryShard.getLastKnownGlobalCheckpoint() && (replicaGlobalCheckpoint < checkpoint)));
    // simulate that the background sync advanced the global checkpoint on the replica
    primaryShard.updateGlobalCheckpointForShard(replicaAllocationId, primaryShard.getLastKnownGlobalCheckpoint());
    // reset our boolean so that we can assert after another simulated maybe sync
    synced.set(false);
    primaryShard.maybeSyncGlobalCheckpoint("test");
    // this time there should not be a sync since all the replica copies are caught up with the primary
    assertFalse(synced.get());
    closeShards(replicaShard, primaryShard);
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) InternalEngineFactory(org.opensearch.index.engine.InternalEngineFactory) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) TestShardRouting.newShardRouting(org.opensearch.cluster.routing.TestShardRouting.newShardRouting) ShardRouting(org.opensearch.cluster.routing.ShardRouting) TestShardRouting(org.opensearch.cluster.routing.TestShardRouting) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) IndexScopedSettings(org.opensearch.common.settings.IndexScopedSettings) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings)

Aggregations

InternalEngineFactory (org.opensearch.index.engine.InternalEngineFactory)17 ShardRouting (org.opensearch.cluster.routing.ShardRouting)14 Settings (org.opensearch.common.settings.Settings)12 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)11 IOException (java.io.IOException)9 IndexSettings (org.opensearch.index.IndexSettings)9 EngineConfigFactory (org.opensearch.index.engine.EngineConfigFactory)8 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)7 TestShardRouting.newShardRouting (org.opensearch.cluster.routing.TestShardRouting.newShardRouting)7 CountDownLatch (java.util.concurrent.CountDownLatch)6 AlreadyClosedException (org.apache.lucene.store.AlreadyClosedException)6 Matchers.containsString (org.hamcrest.Matchers.containsString)6 Store (org.opensearch.index.store.Store)6 Set (java.util.Set)5 Matchers.equalTo (org.hamcrest.Matchers.equalTo)5 OpenSearchException (org.opensearch.OpenSearchException)5 Version (org.opensearch.Version)5 ActionListener (org.opensearch.action.ActionListener)5 IndexRequest (org.opensearch.action.index.IndexRequest)5 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)5