Merge branch 'cassandra-4.0' into cassandra-4.1

Closes #2968
This commit is contained in:
Paulo Motta 2024-01-10 11:17:01 -05:00
commit 3d1b981d89
6 changed files with 61 additions and 13 deletions

View File

@ -8,6 +8,7 @@
* Allow empty keystore_password in encryption_options (CASSANDRA-18778)
* Skip ColumnFamilyStore#topPartitions initialization when client or tool mode (CASSANDRA-18697)
Merged from 4.0:
* Fix Gossiper::hasMajorVersion3Nodes to return false during minor upgrade (CASSANDRA-18999)
* Revert unnecessary read lock acquisition when reading ring version in TokenMetadata introduced in CASSANDRA-16286 (CASSANDRA-19107)
* Support max SSTable size in sorted CQLSSTableWriter (CASSANDRA-18941)
* Fix nodetool repair_admin summarize-pending command to not throw exception (CASSANDRA-19014)

View File

@ -187,6 +187,7 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
* This property and anything that checks it should be removed in 5.0
*/
private volatile boolean upgradeInProgressPossible = true;
private volatile boolean hasNodeWithUnknownVersion = false;
public void clearUnsafe()
{
@ -223,14 +224,14 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
}
// Check the release version of all the peers it heard of. Not necessary the peer that it has/had contacted with.
boolean allHostsHaveKnownVersion = true;
hasNodeWithUnknownVersion = false;
for (InetAddressAndPort host : endpointStateMap.keySet())
{
CassandraVersion version = getReleaseVersion(host);
//Raced with changes to gossip state, wait until next iteration
if (version == null)
allHostsHaveKnownVersion = false;
hasNodeWithUnknownVersion = true;
else if (version.compareTo(minVersion) < 0)
minVersion = version;
}
@ -238,7 +239,7 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
if (minVersion.compareTo(SystemKeyspace.CURRENT_VERSION) < 0)
return new ExpiringMemoizingSupplier.Memoized<>(minVersion);
if (!allHostsHaveKnownVersion)
if (hasNodeWithUnknownVersion)
return new ExpiringMemoizingSupplier.NotMemoized<>(minVersion);
upgradeInProgressPossible = false;
@ -1526,7 +1527,7 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
EndpointState localEpStatePtr = endpointStateMap.get(ep);
EndpointState remoteState = entry.getValue();
if (!hasMajorVersion3Nodes())
if (!hasMajorVersion3OrUnknownNodes())
remoteState.removeMajorVersion3LegacyApplicationStates();
/*
@ -1614,7 +1615,7 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
localState.addApplicationStates(updatedStates);
// get rid of legacy fields once the cluster is not in mixed mode
if (!hasMajorVersion3Nodes())
if (!hasMajorVersion3OrUnknownNodes())
localState.removeMajorVersion3LegacyApplicationStates();
// need to run STATUS or STATUS_WITH_PORT first to handle BOOT_REPLACE correctly (else won't be a member, so TOKENS won't be processed)
@ -2352,12 +2353,12 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
* Returns {@code false} only if the information about the version of each node in the cluster is available and
* ALL the nodes are on 4.0+ (regardless of the patch version).
*/
public boolean hasMajorVersion3Nodes()
public boolean hasMajorVersion3OrUnknownNodes()
{
return isUpgradingFromVersionLowerThan(CassandraVersion.CASSANDRA_4_0) || // this is quite obvious
// however if we discovered only nodes at current version so far (in particular only this node),
// but still there are nodes with unknown version, we also want to report that the cluster may have nodes at 3.x
upgradeInProgressPossible && !isUpgradingFromVersionLowerThan(SystemKeyspace.CURRENT_VERSION.familyLowerBound.get());
hasNodeWithUnknownVersion;
}
/**

View File

@ -227,7 +227,7 @@ public final class SystemDistributedKeyspace
{
// Don't record repair history if an upgrade is in progress as version 3 nodes generates errors
// due to schema differences
boolean includeNewColumns = !Gossiper.instance.hasMajorVersion3Nodes();
boolean includeNewColumns = !Gossiper.instance.hasMajorVersion3OrUnknownNodes();
InetAddressAndPort coordinator = FBUtilities.getBroadcastAddressAndPort();
Set<String> participants = Sets.newHashSet();

View File

@ -122,7 +122,7 @@ public final class TraceKeyspace
rb.ttl(ttl)
.add("client", client)
.add("coordinator", FBUtilities.getBroadcastAddressAndPort().getAddress());
if (!Gossiper.instance.hasMajorVersion3Nodes())
if (!Gossiper.instance.hasMajorVersion3OrUnknownNodes())
rb.add("coordinator_port", FBUtilities.getBroadcastAddressAndPort().getPort());
rb.add("request", request)
.add("started_at", new Date(startedAt))
@ -149,7 +149,7 @@ public final class TraceKeyspace
rowBuilder.add("activity", message)
.add("source", FBUtilities.getBroadcastAddressAndPort().getAddress());
if (!Gossiper.instance.hasMajorVersion3Nodes())
if (!Gossiper.instance.hasMajorVersion3OrUnknownNodes())
rowBuilder.add("source_port", FBUtilities.getBroadcastAddressAndPort().getPort());
rowBuilder.add("thread", threadName);

View File

@ -882,7 +882,7 @@ public class Util
/**
* Setups Gossiper to mimic the upgrade behaviour when {@link Gossiper#isUpgradingFromVersionLowerThan(CassandraVersion)}
* or {@link Gossiper#hasMajorVersion3Nodes()} is called.
* or {@link Gossiper#hasMajorVersion3OrUnknownNodes()} is called.
*/
public static void setUpgradeFromVersion(String version)
{

View File

@ -136,7 +136,7 @@ public class GossiperTest
assertFalse(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.0")) < 0);
assertTrue(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.1")) < 0);
assertTrue(Gossiper.instance.hasMajorVersion3Nodes());
assertTrue(Gossiper.instance.hasMajorVersion3OrUnknownNodes());
Gossiper.instance.endpointStateMap.remove(InetAddressAndPort.getByName("127.0.0.3"));
Gossiper.instance.liveEndpoints.remove(InetAddressAndPort.getByName("127.0.0.3"));
@ -144,7 +144,7 @@ public class GossiperTest
assertFalse(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.0")) < 0);
assertFalse(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.1")) < 0);
assertTrue(Gossiper.instance.upgradeFromVersionSupplier.get().value().compareTo(new CassandraVersion("3.12")) < 0);
assertTrue(Gossiper.instance.hasMajorVersion3Nodes());
assertTrue(Gossiper.instance.hasMajorVersion3OrUnknownNodes());
Gossiper.instance.endpointStateMap.remove(InetAddressAndPort.getByName("127.0.0.2"));
Gossiper.instance.liveEndpoints.remove(InetAddressAndPort.getByName("127.0.0.2"));
@ -152,6 +152,52 @@ public class GossiperTest
assertEquals(SystemKeyspace.CURRENT_VERSION, Gossiper.instance.upgradeFromVersionSupplier.get().value());
}
@Test
public void testHasVersion3NodesShouldReturnFalseWhenNoVersion3NodesDetectedAndCassandra4UpgradeInProgress() throws Exception
{
Gossiper.instance.start(0);
Gossiper.instance.expireUpgradeFromVersion();
VersionedValue.VersionedValueFactory factory = new VersionedValue.VersionedValueFactory(null);
EndpointState es = new EndpointState((HeartBeatState) null);
es.addApplicationState(ApplicationState.RELEASE_VERSION, factory.releaseVersion(CURRENT_VERSION.toString()));
Gossiper.instance.endpointStateMap.put(InetAddressAndPort.getByName("127.0.0.1"), es);
Gossiper.instance.liveEndpoints.add(InetAddressAndPort.getByName("127.0.0.1"));
es = new EndpointState((HeartBeatState) null);
String previousPatchVersion = String.valueOf(CURRENT_VERSION.major) + '.' + (CURRENT_VERSION.minor) + '.' + Math.max(CURRENT_VERSION.patch - 1, 0);
es.addApplicationState(ApplicationState.RELEASE_VERSION, factory.releaseVersion(previousPatchVersion));
Gossiper.instance.endpointStateMap.put(InetAddressAndPort.getByName("127.0.0.2"), es);
Gossiper.instance.liveEndpoints.add(InetAddressAndPort.getByName("127.0.0.2"));
assertFalse(Gossiper.instance.hasMajorVersion3OrUnknownNodes());
Gossiper.instance.endpointStateMap.remove(InetAddressAndPort.getByName("127.0.0.2"));
Gossiper.instance.liveEndpoints.remove(InetAddressAndPort.getByName("127.0.0.2"));
}
@Test
public void testHasVersion3NodesShouldReturnTrueWhenNoVersion3NodesDetectedButNotAllVersionsKnown() throws Exception
{
Gossiper.instance.start(0);
Gossiper.instance.expireUpgradeFromVersion();
VersionedValue.VersionedValueFactory factory = new VersionedValue.VersionedValueFactory(null);
EndpointState es = new EndpointState((HeartBeatState) null);
es.addApplicationState(ApplicationState.RELEASE_VERSION, null);
Gossiper.instance.endpointStateMap.put(InetAddressAndPort.getByName("127.0.0.3"), es);
Gossiper.instance.liveEndpoints.add(InetAddressAndPort.getByName("127.0.0.3"));
es = new EndpointState((HeartBeatState) null);
String previousPatchVersion = String.valueOf(CURRENT_VERSION.major) + '.' + (CURRENT_VERSION.minor) + '.' + Math.max(CURRENT_VERSION.patch - 1, 0);
es.addApplicationState(ApplicationState.RELEASE_VERSION, factory.releaseVersion(previousPatchVersion));
Gossiper.instance.endpointStateMap.put(InetAddressAndPort.getByName("127.0.0.2"), es);
Gossiper.instance.liveEndpoints.add(InetAddressAndPort.getByName("127.0.0.2"));
assertTrue(Gossiper.instance.hasMajorVersion3OrUnknownNodes());
Gossiper.instance.endpointStateMap.remove(InetAddressAndPort.getByName("127.0.0.2"));
Gossiper.instance.liveEndpoints.remove(InetAddressAndPort.getByName("127.0.0.2"));
}
@Test
public void testLargeGenerationJump() throws UnknownHostException, InterruptedException
{