This is an automated email from the ASF dual-hosted git repository.
frankgh pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new a80663de61 Fix NoSuchElementException on dropped keyspace during Paxos
cleanup
a80663de61 is described below
commit a80663de61cb27781910b2ff64e99a239bbe5944
Author: Abe Ratnofsky <[email protected]>
AuthorDate: Wed Feb 12 11:08:40 2025 -0500
Fix NoSuchElementException on dropped keyspace during Paxos cleanup
patch by Abe Ratnofsky; reviewed by Francisco Guerrero, Sam Tunnicliffe for
CASSANDRA-20320
---
.../cassandra/service/paxos/PaxosRepair.java | 7 ++--
.../cleanup/PaxosCleanupLocalCoordinator.java | 10 ++++-
.../distributed/test/PaxosRepair2Test.java | 49 ++++++++++++++++++++++
3 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/src/java/org/apache/cassandra/service/paxos/PaxosRepair.java
b/src/java/org/apache/cassandra/service/paxos/PaxosRepair.java
index 016086cbb1..e36e1d3522 100644
--- a/src/java/org/apache/cassandra/service/paxos/PaxosRepair.java
+++ b/src/java/org/apache/cassandra/service/paxos/PaxosRepair.java
@@ -677,16 +677,15 @@ public class PaxosRepair extends AbstractPaxosRepair
return result;
}
- static boolean validatePeerCompatibility(SharedContext ctx, TableMetadata
table, Range<Token> range)
+ static boolean validatePeerCompatibility(SharedContext ctx,
ClusterMetadata metadata, TableMetadata table, Range<Token> range)
{
- ClusterMetadata metadata = ClusterMetadata.current();
Participants participants = Participants.get(metadata, table,
range.right, ConsistencyLevel.SERIAL, r ->
ctx.failureDetector().isAlive(r.endpoint()));
return Iterables.all(participants.all, (participant) ->
validatePeerCompatibility(metadata, participant));
}
- public static boolean validatePeerCompatibility(SharedContext ctx,
TableMetadata table, Collection<Range<Token>> ranges)
+ public static boolean validatePeerCompatibility(SharedContext ctx,
ClusterMetadata metadata, TableMetadata table, Collection<Range<Token>> ranges)
{
- return Iterables.all(ranges, range -> validatePeerCompatibility(ctx,
table, range));
+ return Iterables.all(ranges, range -> validatePeerCompatibility(ctx,
metadata, table, range));
}
public static void shutdownAndWait(long timeout, TimeUnit units) throws
InterruptedException, TimeoutException
diff --git
a/src/java/org/apache/cassandra/service/paxos/cleanup/PaxosCleanupLocalCoordinator.java
b/src/java/org/apache/cassandra/service/paxos/cleanup/PaxosCleanupLocalCoordinator.java
index f91846bc9f..a53fec3e60 100644
---
a/src/java/org/apache/cassandra/service/paxos/cleanup/PaxosCleanupLocalCoordinator.java
+++
b/src/java/org/apache/cassandra/service/paxos/cleanup/PaxosCleanupLocalCoordinator.java
@@ -40,6 +40,7 @@ import org.apache.cassandra.service.paxos.AbstractPaxosRepair;
import org.apache.cassandra.service.paxos.PaxosRepair;
import org.apache.cassandra.service.paxos.PaxosState;
import org.apache.cassandra.service.paxos.uncommitted.UncommittedPaxosKey;
+import org.apache.cassandra.tcm.ClusterMetadata;
import org.apache.cassandra.utils.CloseableIterator;
import org.apache.cassandra.utils.concurrent.AsyncFuture;
@@ -84,7 +85,14 @@ public class PaxosCleanupLocalCoordinator extends
AsyncFuture<PaxosCleanupRespon
return;
}
- if (!PaxosRepair.validatePeerCompatibility(ctx, table, ranges))
+ ClusterMetadata metadata = ClusterMetadata.current();
+ if (metadata.schema.getKeyspace(table.keyspace) == null)
+ {
+ fail("Unknown keyspace: " + table.keyspace);
+ return;
+ }
+
+ if (!PaxosRepair.validatePeerCompatibility(ctx, metadata, table,
ranges))
{
fail("Unsupported peer versions for " + tableId + ' ' +
ranges.toString());
return;
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/PaxosRepair2Test.java
b/test/distributed/org/apache/cassandra/distributed/test/PaxosRepair2Test.java
index 8b043ab6aa..175f70c797 100644
---
a/test/distributed/org/apache/cassandra/distributed/test/PaxosRepair2Test.java
+++
b/test/distributed/org/apache/cassandra/distributed/test/PaxosRepair2Test.java
@@ -23,12 +23,17 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Iterators;
import com.google.common.collect.Sets;
import org.apache.cassandra.distributed.shared.WithProperties;
+import org.apache.cassandra.repair.SharedContext;
+import org.apache.cassandra.service.paxos.cleanup.PaxosCleanupLocalCoordinator;
+import org.apache.cassandra.service.paxos.cleanup.PaxosCleanupResponse;
+import org.apache.cassandra.utils.Shared;
import org.awaitility.Awaitility;
import org.junit.Assert;
import org.junit.Test;
@@ -456,6 +461,13 @@ public class PaxosRepair2Test extends TestBaseImpl
}
}
+ @Shared(scope = Shared.Scope.ANY)
+ public static class Conditions
+ {
+ public java.util.concurrent.CountDownLatch beforeKeyspaceDrop = new
CountDownLatch(1);
+ public java.util.concurrent.CountDownLatch afterKeyspaceDrop = new
CountDownLatch(1);
+ }
+
@Test
public void legacyPurgeRepairLoop() throws Exception
{
@@ -573,6 +585,43 @@ public class PaxosRepair2Test extends TestBaseImpl
assertUncommitted(cluster.get(1), KEYSPACE, TABLE, 0);
assertUncommitted(cluster.get(2), KEYSPACE, TABLE, 0);
assertUncommitted(cluster.get(3), KEYSPACE, TABLE, 0);
+
+ Conditions conditions = new Conditions();
+
+ Thread keyspaceDropTask = new Thread(() -> {
+ try
+ {
+ conditions.beforeKeyspaceDrop.await();
+ cluster.schemaChange("DROP KEYSPACE " + KEYSPACE, 3);
+ conditions.afterKeyspaceDrop.countDown();
+ }
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException(e);
+ }
+ });
+
+ keyspaceDropTask.start();
+
+ boolean failedAsExpected =
cluster.get(3).applyOnInstance(conds -> {
+ try
+ {
+ TableId tableId =
Schema.instance.getTableMetadata(KEYSPACE, TABLE).id;
+ Token token =
DatabaseDescriptor.getPartitioner().getMinimumToken();
+ Collection<Range<Token>> ranges =
Collections.singleton(new Range<>(token, token));
+ PaxosCleanupLocalCoordinator repair =
PaxosCleanupLocalCoordinator.createForAutoRepair(SharedContext.Global.instance,
tableId, ranges);
+ conds.beforeKeyspaceDrop.countDown();
+ conds.afterKeyspaceDrop.await();
+ repair.start();
+ PaxosCleanupResponse result = repair.get();
+ return !result.wasSuccessful &&
result.message.contains("Unknown keyspace: " + KEYSPACE);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }, conditions);
+ Assert.assertTrue(failedAsExpected);
}
}
finally
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]