Search in sources :

Example 1 with NodeMetadata

use of org.opensearch.env.NodeMetadata in project OpenSearch by opensearch-project.

the class GatewayMetaState method start.

public void start(Settings settings, TransportService transportService, ClusterService clusterService, MetaStateService metaStateService, MetadataIndexUpgradeService metadataIndexUpgradeService, MetadataUpgrader metadataUpgrader, PersistedClusterStateService persistedClusterStateService) {
    assert persistedState.get() == null : "should only start once, but already have " + persistedState.get();
    if (DiscoveryNode.isMasterNode(settings) || DiscoveryNode.isDataNode(settings)) {
        try {
            final PersistedClusterStateService.OnDiskState onDiskState = persistedClusterStateService.loadBestOnDiskState();
            Metadata metadata = onDiskState.metadata;
            long lastAcceptedVersion = onDiskState.lastAcceptedVersion;
            long currentTerm = onDiskState.currentTerm;
            if (onDiskState.empty()) {
                assert Version.CURRENT.major <= LegacyESVersion.V_7_0_0.major + 1 : "legacy metadata loader is not needed anymore from v9 onwards";
                final Tuple<Manifest, Metadata> legacyState = metaStateService.loadFullState();
                if (legacyState.v1().isEmpty() == false) {
                    metadata = legacyState.v2();
                    lastAcceptedVersion = legacyState.v1().getClusterStateVersion();
                    currentTerm = legacyState.v1().getCurrentTerm();
                }
            }
            PersistedState persistedState = null;
            boolean success = false;
            try {
                final ClusterState clusterState = prepareInitialClusterState(transportService, clusterService, ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.get(settings)).version(lastAcceptedVersion).metadata(upgradeMetadataForNode(metadata, metadataIndexUpgradeService, metadataUpgrader)).build());
                if (DiscoveryNode.isMasterNode(settings)) {
                    persistedState = new LucenePersistedState(persistedClusterStateService, currentTerm, clusterState);
                } else {
                    persistedState = new AsyncLucenePersistedState(settings, transportService.getThreadPool(), new LucenePersistedState(persistedClusterStateService, currentTerm, clusterState));
                }
                if (DiscoveryNode.isDataNode(settings)) {
                    // unreference legacy files (only keep them for dangling indices functionality)
                    metaStateService.unreferenceAll();
                } else {
                    // delete legacy files
                    metaStateService.deleteAll();
                }
                // write legacy node metadata to prevent accidental downgrades from spawning empty cluster state
                NodeMetadata.FORMAT.writeAndCleanup(new NodeMetadata(persistedClusterStateService.getNodeId(), Version.CURRENT), persistedClusterStateService.getDataPaths());
                success = true;
            } finally {
                if (success == false) {
                    IOUtils.closeWhileHandlingException(persistedState);
                }
            }
            this.persistedState.set(persistedState);
        } catch (IOException e) {
            throw new OpenSearchException("failed to load metadata", e);
        }
    } else {
        final long currentTerm = 0L;
        final ClusterState clusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.get(settings)).build();
        if (persistedClusterStateService.getDataPaths().length > 0) {
            // cluster uuid as coordinating-only nodes do not snap into a cluster as they carry no state
            try (PersistedClusterStateService.Writer persistenceWriter = persistedClusterStateService.createWriter()) {
                persistenceWriter.writeFullStateAndCommit(currentTerm, clusterState);
            } catch (IOException e) {
                throw new OpenSearchException("failed to load metadata", e);
            }
            try {
                // delete legacy cluster state files
                metaStateService.deleteAll();
                // write legacy node metadata to prevent downgrades from spawning empty cluster state
                NodeMetadata.FORMAT.writeAndCleanup(new NodeMetadata(persistedClusterStateService.getNodeId(), Version.CURRENT), persistedClusterStateService.getDataPaths());
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
        persistedState.set(new InMemoryPersistedState(currentTerm, clusterState));
    }
}
Also used : PersistedState(org.opensearch.cluster.coordination.CoordinationState.PersistedState) InMemoryPersistedState(org.opensearch.cluster.coordination.InMemoryPersistedState) ClusterState(org.opensearch.cluster.ClusterState) Metadata(org.opensearch.cluster.metadata.Metadata) NodeMetadata(org.opensearch.env.NodeMetadata) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) CoordinationMetadata(org.opensearch.cluster.coordination.CoordinationMetadata) IndexTemplateMetadata(org.opensearch.cluster.metadata.IndexTemplateMetadata) UncheckedIOException(java.io.UncheckedIOException) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) Manifest(org.opensearch.cluster.metadata.Manifest) NodeMetadata(org.opensearch.env.NodeMetadata) InMemoryPersistedState(org.opensearch.cluster.coordination.InMemoryPersistedState) OpenSearchException(org.opensearch.OpenSearchException)

Example 2 with NodeMetadata

use of org.opensearch.env.NodeMetadata in project OpenSearch by opensearch-project.

the class Node method start.

/**
 * Start the node. If the node is already started, this method is no-op.
 */
public Node start() throws NodeValidationException {
    if (!lifecycle.moveToStarted()) {
        return this;
    }
    logger.info("starting ...");
    pluginLifecycleComponents.forEach(LifecycleComponent::start);
    injector.getInstance(MappingUpdatedAction.class).setClient(client);
    injector.getInstance(IndicesService.class).start();
    injector.getInstance(IndicesClusterStateService.class).start();
    injector.getInstance(SnapshotsService.class).start();
    injector.getInstance(SnapshotShardsService.class).start();
    injector.getInstance(RepositoriesService.class).start();
    injector.getInstance(SearchService.class).start();
    injector.getInstance(FsHealthService.class).start();
    nodeService.getMonitorService().start();
    final ClusterService clusterService = injector.getInstance(ClusterService.class);
    final NodeConnectionsService nodeConnectionsService = injector.getInstance(NodeConnectionsService.class);
    nodeConnectionsService.start();
    clusterService.setNodeConnectionsService(nodeConnectionsService);
    injector.getInstance(GatewayService.class).start();
    Discovery discovery = injector.getInstance(Discovery.class);
    clusterService.getMasterService().setClusterStatePublisher(discovery::publish);
    // Start the transport service now so the publish address will be added to the local disco node in ClusterService
    TransportService transportService = injector.getInstance(TransportService.class);
    transportService.getTaskManager().setTaskResultsService(injector.getInstance(TaskResultsService.class));
    transportService.getTaskManager().setTaskCancellationService(new TaskCancellationService(transportService));
    transportService.start();
    assert localNodeFactory.getNode() != null;
    assert transportService.getLocalNode().equals(localNodeFactory.getNode()) : "transportService has a different local node than the factory provided";
    injector.getInstance(PeerRecoverySourceService.class).start();
    // Load (and maybe upgrade) the metadata stored on disk
    final GatewayMetaState gatewayMetaState = injector.getInstance(GatewayMetaState.class);
    gatewayMetaState.start(settings(), transportService, clusterService, injector.getInstance(MetaStateService.class), injector.getInstance(MetadataIndexUpgradeService.class), injector.getInstance(MetadataUpgrader.class), injector.getInstance(PersistedClusterStateService.class));
    if (Assertions.ENABLED) {
        try {
            assert injector.getInstance(MetaStateService.class).loadFullState().v1().isEmpty();
            final NodeMetadata nodeMetadata = NodeMetadata.FORMAT.loadLatestState(logger, NamedXContentRegistry.EMPTY, nodeEnvironment.nodeDataPaths());
            assert nodeMetadata != null;
            assert nodeMetadata.nodeVersion().equals(Version.CURRENT);
            assert nodeMetadata.nodeId().equals(localNodeFactory.getNode().getId());
        } catch (IOException e) {
            assert false : e;
        }
    }
    // we load the global state here (the persistent part of the cluster state stored on disk) to
    // pass it to the bootstrap checks to allow plugins to enforce certain preconditions based on the recovered state.
    final Metadata onDiskMetadata = gatewayMetaState.getPersistedState().getLastAcceptedState().metadata();
    // this is never null
    assert onDiskMetadata != null : "metadata is null but shouldn't";
    validateNodeBeforeAcceptingRequests(new BootstrapContext(environment, onDiskMetadata), transportService.boundAddress(), pluginsService.filterPlugins(Plugin.class).stream().flatMap(p -> p.getBootstrapChecks().stream()).collect(Collectors.toList()));
    clusterService.addStateApplier(transportService.getTaskManager());
    // start after transport service so the local disco is known
    // start before cluster service so that it can set initial state on ClusterApplierService
    discovery.start();
    clusterService.start();
    assert clusterService.localNode().equals(localNodeFactory.getNode()) : "clusterService has a different local node than the factory provided";
    transportService.acceptIncomingRequests();
    discovery.startInitialJoin();
    final TimeValue initialStateTimeout = DiscoverySettings.INITIAL_STATE_TIMEOUT_SETTING.get(settings());
    configureNodeAndClusterIdStateListener(clusterService);
    if (initialStateTimeout.millis() > 0) {
        final ThreadPool thread = injector.getInstance(ThreadPool.class);
        ClusterState clusterState = clusterService.state();
        ClusterStateObserver observer = new ClusterStateObserver(clusterState, clusterService, null, logger, thread.getThreadContext());
        if (clusterState.nodes().getMasterNodeId() == null) {
            logger.debug("waiting to join the cluster. timeout [{}]", initialStateTimeout);
            final CountDownLatch latch = new CountDownLatch(1);
            observer.waitForNextChange(new ClusterStateObserver.Listener() {

                @Override
                public void onNewClusterState(ClusterState state) {
                    latch.countDown();
                }

                @Override
                public void onClusterServiceClose() {
                    latch.countDown();
                }

                @Override
                public void onTimeout(TimeValue timeout) {
                    logger.warn("timed out while waiting for initial discovery state - timeout: {}", initialStateTimeout);
                    latch.countDown();
                }
            }, state -> state.nodes().getMasterNodeId() != null, initialStateTimeout);
            try {
                latch.await();
            } catch (InterruptedException e) {
                throw new OpenSearchTimeoutException("Interrupted while waiting for initial discovery state");
            }
        }
    }
    injector.getInstance(HttpServerTransport.class).start();
    if (WRITE_PORTS_FILE_SETTING.get(settings())) {
        TransportService transport = injector.getInstance(TransportService.class);
        writePortsFile("transport", transport.boundAddress());
        HttpServerTransport http = injector.getInstance(HttpServerTransport.class);
        writePortsFile("http", http.boundAddress());
    }
    logger.info("started");
    pluginsService.filterPlugins(ClusterPlugin.class).forEach(ClusterPlugin::onNodeStarted);
    return this;
}
Also used : OpenSearchTimeoutException(org.opensearch.OpenSearchTimeoutException) SnapshotsService(org.opensearch.snapshots.SnapshotsService) SnapshotShardsService(org.opensearch.snapshots.SnapshotShardsService) NodeConnectionsService(org.opensearch.cluster.NodeConnectionsService) Metadata(org.opensearch.cluster.metadata.Metadata) NodeMetadata(org.opensearch.env.NodeMetadata) IndexTemplateMetadata(org.opensearch.cluster.metadata.IndexTemplateMetadata) ThreadPool(org.opensearch.threadpool.ThreadPool) MetadataUpgrader(org.opensearch.plugins.MetadataUpgrader) BootstrapContext(org.opensearch.bootstrap.BootstrapContext) TaskResultsService(org.opensearch.tasks.TaskResultsService) HttpServerTransport(org.opensearch.http.HttpServerTransport) GatewayMetaState(org.opensearch.gateway.GatewayMetaState) MetaStateService(org.opensearch.gateway.MetaStateService) IndicesClusterStateService(org.opensearch.indices.cluster.IndicesClusterStateService) LifecycleComponent(org.opensearch.common.component.LifecycleComponent) SearchService(org.opensearch.search.SearchService) PeerRecoverySourceService(org.opensearch.indices.recovery.PeerRecoverySourceService) TimeValue(org.opensearch.common.unit.TimeValue) FsHealthService(org.opensearch.monitor.fs.FsHealthService) ClusterState(org.opensearch.cluster.ClusterState) ClusterStateObserver(org.opensearch.cluster.ClusterStateObserver) ClusterPlugin(org.opensearch.plugins.ClusterPlugin) Discovery(org.opensearch.discovery.Discovery) IndicesService(org.opensearch.indices.IndicesService) MetadataIndexUpgradeService(org.opensearch.cluster.metadata.MetadataIndexUpgradeService) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) GatewayService(org.opensearch.gateway.GatewayService) NodeMetadata(org.opensearch.env.NodeMetadata) ClusterService(org.opensearch.cluster.service.ClusterService) PersistentTasksClusterService(org.opensearch.persistent.PersistentTasksClusterService) RemoteClusterService(org.opensearch.transport.RemoteClusterService) TransportService(org.opensearch.transport.TransportService) SearchTransportService(org.opensearch.action.search.SearchTransportService) RepositoriesService(org.opensearch.repositories.RepositoriesService) MappingUpdatedAction(org.opensearch.cluster.action.index.MappingUpdatedAction) PersistedClusterStateService(org.opensearch.gateway.PersistedClusterStateService) TaskCancellationService(org.opensearch.tasks.TaskCancellationService)

Example 3 with NodeMetadata

use of org.opensearch.env.NodeMetadata in project OpenSearch by opensearch-project.

the class PeerRecoveryRetentionLeaseCreationIT method testCanRecoverFromStoreWithoutPeerRecoveryRetentionLease.

@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/48701")
public void testCanRecoverFromStoreWithoutPeerRecoveryRetentionLease() throws Exception {
    /*
         * In a full cluster restart from a version without peer-recovery retention leases, the leases on disk will not include a lease for
         * the local node. The same sort of thing can happen in weird situations involving dangling indices. This test ensures that a
         * primary that is recovering from store creates a lease for itself.
         */
    internalCluster().startMasterOnlyNode();
    final String dataNode = internalCluster().startDataOnlyNode();
    final Path[] nodeDataPaths = internalCluster().getInstance(NodeEnvironment.class, dataNode).nodeDataPaths();
    assertAcked(prepareCreate("index").setSettings(Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0).put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true).put(IndexMetadata.SETTING_VERSION_CREATED, // simulate a version which supports soft deletes with which this node is compatible
    VersionUtils.randomVersionBetween(random(), Version.CURRENT.minimumIndexCompatibilityVersion(), Version.CURRENT))));
    ensureGreen("index");
    // Change the node ID so that the persisted retention lease no longer applies.
    final String oldNodeId = client().admin().cluster().prepareNodesInfo(dataNode).clear().get().getNodes().get(0).getNode().getId();
    final String newNodeId = randomValueOtherThan(oldNodeId, () -> UUIDs.randomBase64UUID(random()));
    internalCluster().restartNode(dataNode, new InternalTestCluster.RestartCallback() {

        @Override
        public Settings onNodeStopped(String nodeName) throws Exception {
            final NodeMetadata nodeMetadata = new NodeMetadata(newNodeId, Version.CURRENT);
            NodeMetadata.FORMAT.writeAndCleanup(nodeMetadata, nodeDataPaths);
            return Settings.EMPTY;
        }
    });
    ensureGreen("index");
    assertThat(client().admin().cluster().prepareNodesInfo(dataNode).clear().get().getNodes().get(0).getNode().getId(), equalTo(newNodeId));
    final RetentionLeases retentionLeases = client().admin().indices().prepareStats("index").get().getShards()[0].getRetentionLeaseStats().retentionLeases();
    assertTrue("expected lease for [" + newNodeId + "] in " + retentionLeases, retentionLeases.contains(ReplicationTracker.getPeerRecoveryRetentionLeaseId(newNodeId)));
}
Also used : Path(java.nio.file.Path) NodeMetadata(org.opensearch.env.NodeMetadata) NodeEnvironment(org.opensearch.env.NodeEnvironment) InternalTestCluster(org.opensearch.test.InternalTestCluster) Settings(org.opensearch.common.settings.Settings) IndexSettings(org.opensearch.index.IndexSettings)

Example 4 with NodeMetadata

use of org.opensearch.env.NodeMetadata in project OpenSearch by opensearch-project.

the class OpenSearchNodeCommand method createPersistedClusterStateService.

public static PersistedClusterStateService createPersistedClusterStateService(Settings settings, Path[] dataPaths) throws IOException {
    final NodeMetadata nodeMetadata = PersistedClusterStateService.nodeMetadata(dataPaths);
    if (nodeMetadata == null) {
        throw new OpenSearchException(NO_NODE_METADATA_FOUND_MSG);
    }
    String nodeId = nodeMetadata.nodeId();
    return new PersistedClusterStateService(dataPaths, nodeId, namedXContentRegistry, BigArrays.NON_RECYCLING_INSTANCE, new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), () -> 0L);
}
Also used : NodeMetadata(org.opensearch.env.NodeMetadata) ClusterSettings(org.opensearch.common.settings.ClusterSettings) OpenSearchException(org.opensearch.OpenSearchException) PersistedClusterStateService(org.opensearch.gateway.PersistedClusterStateService)

Example 5 with NodeMetadata

use of org.opensearch.env.NodeMetadata in project OpenSearch by opensearch-project.

the class PersistedClusterStateService method nodeMetadata.

/**
 * Returns the node metadata for the given data paths, and checks if the node ids are unique
 * @param dataPaths the data paths to scan
 */
@Nullable
public static NodeMetadata nodeMetadata(Path... dataPaths) throws IOException {
    String nodeId = null;
    Version version = null;
    for (final Path dataPath : dataPaths) {
        final Path indexPath = dataPath.resolve(METADATA_DIRECTORY_NAME);
        if (Files.exists(indexPath)) {
            try (DirectoryReader reader = DirectoryReader.open(new NIOFSDirectory(dataPath.resolve(METADATA_DIRECTORY_NAME)))) {
                final Map<String, String> userData = reader.getIndexCommit().getUserData();
                assert userData.get(NODE_VERSION_KEY) != null;
                final String thisNodeId = userData.get(NODE_ID_KEY);
                assert thisNodeId != null;
                if (nodeId != null && nodeId.equals(thisNodeId) == false) {
                    throw new IllegalStateException("unexpected node ID in metadata, found [" + thisNodeId + "] in [" + dataPath + "] but expected [" + nodeId + "]");
                } else if (nodeId == null) {
                    nodeId = thisNodeId;
                    version = Version.fromId(Integer.parseInt(userData.get(NODE_VERSION_KEY)));
                }
            } catch (IndexNotFoundException e) {
                logger.debug(new ParameterizedMessage("no on-disk state at {}", indexPath), e);
            }
        }
    }
    if (nodeId == null) {
        return null;
    }
    return new NodeMetadata(nodeId, version);
}
Also used : Path(java.nio.file.Path) NodeMetadata(org.opensearch.env.NodeMetadata) NIOFSDirectory(org.apache.lucene.store.NIOFSDirectory) Version(org.opensearch.Version) DirectoryReader(org.apache.lucene.index.DirectoryReader) IndexNotFoundException(org.apache.lucene.index.IndexNotFoundException) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) Nullable(org.opensearch.common.Nullable)

Aggregations

NodeMetadata (org.opensearch.env.NodeMetadata)6 Path (java.nio.file.Path)3 OpenSearchException (org.opensearch.OpenSearchException)3 IOException (java.io.IOException)2 ClusterState (org.opensearch.cluster.ClusterState)2 IndexTemplateMetadata (org.opensearch.cluster.metadata.IndexTemplateMetadata)2 Metadata (org.opensearch.cluster.metadata.Metadata)2 PersistedClusterStateService (org.opensearch.gateway.PersistedClusterStateService)2 UncheckedIOException (java.io.UncheckedIOException)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)1 DirectoryReader (org.apache.lucene.index.DirectoryReader)1 IndexNotFoundException (org.apache.lucene.index.IndexNotFoundException)1 NIOFSDirectory (org.apache.lucene.store.NIOFSDirectory)1 OpenSearchTimeoutException (org.opensearch.OpenSearchTimeoutException)1 Version (org.opensearch.Version)1 SearchTransportService (org.opensearch.action.search.SearchTransportService)1 BootstrapContext (org.opensearch.bootstrap.BootstrapContext)1 ClusterStateObserver (org.opensearch.cluster.ClusterStateObserver)1 NodeConnectionsService (org.opensearch.cluster.NodeConnectionsService)1