Skip version check if an endpoint is dead state in Gossiper#upgradeFromVersionSupplier

patch by Runtian Liu; reviewed by Stefan Miklosovic and Brandon Williams for CASSANDRA-19187
This commit is contained in:
Runtian Liu 2024-01-10 14:55:22 +01:00 committed by Stefan Miklosovic
parent 290a5990d4
commit ee9e418782
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
4 changed files with 29 additions and 3 deletions

View File

@ -1,4 +1,5 @@
4.0.12
* Skip version check if an endpoint is dead state in Gossiper#upgradeFromVersionSupplier (CASSANDRA-19187)
* 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)

View File

@ -208,10 +208,13 @@ 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.
hasNodeWithUnknownVersion = false;
for (InetAddressAndPort host : endpointStateMap.keySet())
for (Entry<InetAddressAndPort, EndpointState> entry : endpointStateMap.entrySet())
{
CassandraVersion version = getReleaseVersion(host);
CassandraVersion version = getReleaseVersion(entry.getKey());
// if it is dead state, we skip the version check
if (isDeadState(entry.getValue()))
continue;
//Raced with changes to gossip state, wait until next iteration
if (version == null)
hasNodeWithUnknownVersion = true;

View File

@ -101,7 +101,7 @@ public class ExpiringMemoizingSupplier<T> implements Supplier<T>
this.value = value;
}
abstract boolean canMemoize();
public abstract boolean canMemoize();
public T value()
{

View File

@ -195,6 +195,28 @@ public class GossiperTest
Gossiper.instance.liveEndpoints.remove(InetAddressAndPort.getByName("127.0.0.2"));
}
@Test
public void testAssassinatedNodeWillNotContributeToVersionCalculation() throws Exception
{
int initialNodeCount = 3;
Util.createInitialRing(ss, partitioner, endpointTokens, keyTokens, hosts, hostIds, initialNodeCount);
for (int i = 0; i < initialNodeCount; i++)
{
Gossiper.instance.injectApplicationState(hosts.get(i), ApplicationState.RELEASE_VERSION, new VersionedValue.VersionedValueFactory(null).releaseVersion(SystemKeyspace.CURRENT_VERSION.toString()));
}
Gossiper.instance.start(1);
Gossiper.instance.expireUpgradeFromVersion();
// assassinate a non-existing node
Gossiper.instance.assassinateEndpoint("127.0.0.4");
assertTrue(Gossiper.instance.endpointStateMap.containsKey(InetAddressAndPort.getByName("127.0.0.4")));
assertNull(Gossiper.instance.upgradeFromVersionSupplier.get().value());
assertTrue(Gossiper.instance.upgradeFromVersionSupplier.get().canMemoize());
assertFalse(Gossiper.instance.hasMajorVersion3OrUnknownNodes());
assertFalse(Gossiper.instance.isUpgradingFromVersionLowerThan(CassandraVersion.CASSANDRA_3_4));
}
@Test
public void testLargeGenerationJump() throws UnknownHostException, InterruptedException
{