in src/java/org/apache/cassandra/service/StorageService.java [717:874]
public synchronized void initServer() throws ConfigurationException
{
logger.info("Cassandra version: {}", FBUtilities.getReleaseVersionString());
logger.info("Build Date: {}", FBUtilities.getBuildDate());
logger.info("Git SHA: {}", FBUtilities.getGitSHA());
logger.info("CQL version: {}", QueryProcessor.CQL_VERSION);
logger.info("Native protocol supported versions: {} (default: {})",
StringUtils.join(ProtocolVersion.supportedVersions(), ", "), ProtocolVersion.CURRENT);
try
{
// Ensure StorageProxy is initialized on start-up; see CASSANDRA-3797.
Class.forName("org.apache.cassandra.service.StorageProxy");
// also IndexSummaryManager, which is otherwise unreferenced
Class.forName("org.apache.cassandra.io.sstable.indexsummary.IndexSummaryManager");
}
catch (ClassNotFoundException e)
{
throw new AssertionError(e);
}
// daemon threads, like our executors', continue to run while shutdown hooks are invoked
drainOnShutdown = NamedThreadFactory.createThread(new WrappedRunnable()
{
@Override
public void runMayThrow() throws InterruptedException, ExecutionException, IOException
{
drain(true);
try
{
ExecutorUtils.shutdownNowAndWait(1, MINUTES, ScheduledExecutors.scheduledFastTasks);
logger.info("Cassandra shutdown complete");
}
catch (Throwable t)
{
logger.warn("Unable to terminate fast tasks within 1 minute.", t);
}
finally
{
LoggingSupportFactory.getLoggingSupport().onShutdown();
}
}
}, "StorageServiceShutdownHook");
Runtime.getRuntime().addShutdownHook(drainOnShutdown);
Schema.instance.saveSystemKeyspace();
DatabaseDescriptor.getInternodeAuthenticator().setupInternode();
if (ClusterMetadataService.state() == ClusterMetadataService.State.GOSSIP)
{
// register listener before starting gossiper to avoid missing messages
Gossiper.instance.register(new GossipCMSListener());
}
sstablesTracker.register((notification, o) -> {
if (!(notification instanceof SSTablesVersionsInUseChangeNotification))
return;
Set<Version> versions = ((SSTablesVersionsInUseChangeNotification) notification).versionsInUse;
logger.debug("Updating local sstables version in Gossip to {}", versions);
Gossiper.instance.addLocalApplicationState(ApplicationState.SSTABLE_VERSIONS,
valueFactory.sstableVersions(versions));
});
if (SystemKeyspace.wasDecommissioned())
{
if (CassandraRelevantProperties.OVERRIDE_DECOMMISSION.getBoolean())
{
logger.warn("This node was decommissioned, but overriding by operator request.");
}
else
{
throw new ConfigurationException("This node was decommissioned and will not rejoin the ring unless cassandra.override_decommission=true has been set, or all existing data is removed and the node is bootstrapped again");
}
}
if (DatabaseDescriptor.getReplaceTokens().size() > 0 || DatabaseDescriptor.getReplaceNode() != null)
throw new RuntimeException("Replace method removed; use cassandra.replace_address instead");
if (isReplacing())
{
if (SystemKeyspace.bootstrapComplete())
throw new RuntimeException("Cannot replace with a node that is already bootstrapped");
InetAddressAndPort replaceAddress = DatabaseDescriptor.getReplaceAddress();
Directory directory = ClusterMetadata.current().directory;
if (directory.peerId(replaceAddress) == null || directory.peerState(replaceAddress) != JOINED)
throw new RuntimeException(String.format("Cannot replace node %s which is not currently joined", replaceAddress));
BootstrapAndReplace.checkUnsafeReplace(shouldBootstrap());
}
if (isReplacingSameAddress())
{
BootstrapAndReplace.gossipStateToHibernate(ClusterMetadata.current(), ClusterMetadata.currentNullable().myNodeId());
Gossiper.instance.start(SystemKeyspace.incrementAndGetGeneration(), false);
}
else
{
Gossiper.instance.start(SystemKeyspace.incrementAndGetGeneration(),
ClusterMetadataService.state() != ClusterMetadataService.State.GOSSIP); // only populate local state if not running in gossip mode
}
Gossiper.instance.register(this);
Gossiper.instance.addLocalApplicationState(ApplicationState.NET_VERSION, valueFactory.networkVersion());
Gossiper.instance.addLocalApplicationState(ApplicationState.SSTABLE_VERSIONS,
valueFactory.sstableVersions(sstablesTracker.versionsInUse()));
Gossiper.instance.triggerRoundWithCMS();
// Has to be called after the host id has potentially changed
try
{
CacheService.instance.counterCache.loadSavedAsync().get();
}
catch (Throwable t)
{
JVMStabilityInspector.inspectThrowable(t);
logger.warn("Error loading counter cache", t);
}
Gossiper.waitToSettle();
NodeId self;
if (isReplacingSameAddress())
{
self = ClusterMetadata.current().myNodeId();
if (self == null)
throw new IllegalStateException("Tried to replace same address, but node does not seem to be registered");
}
else
{
self = Register.maybeRegister();
}
RegistrationStatus.instance.onRegistration();
Startup.maybeExecuteStartupTransformation(self);
try
{
if (joinRing)
joinRing();
else
{
ClusterMetadata metadata = ClusterMetadata.current();
if (metadata.myNodeState() == JOINED)
BootstrapAndReplace.gossipStateToHibernate(metadata, metadata.myNodeId());
logger.info("Not joining ring as requested. Use JMX (StorageService->joinRing()) to initiate ring joining");
}
}
catch (IOException e)
{
throw new RuntimeException("Could not perform startup sequence and join cluster", e);
}
maybeInitializeServices();
completeInitialization();
}