This is an automated email from the ASF dual-hosted git repository.

jmckenzie 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 0371493772 Warn on unknown directories found in system keyspace 
directory rather than kill node during startup checks
0371493772 is described below

commit 037149377224c5d6854fa4a0cacf44139273bce3
Author: Josh McKenzie <[email protected]>
AuthorDate: Tue Jul 26 15:15:48 2022 -0400

    Warn on unknown directories found in system keyspace directory rather than 
kill node during startup checks
    
    Patch by Jeff Jirsa; reviewed by Josh McKenzie, Sam Tunnicliffe, and Marcus 
Eriksson for CASSANDRA-17777
    
    Co-authored-by: Jeff Jirsa <[email protected]>
    Co-authored-by: Josh McKenzie <[email protected]>
---
 CHANGES.txt                                        |  1 +
 .../org/apache/cassandra/db/SystemKeyspace.java    |  9 ++++++
 .../org/apache/cassandra/service/StartupCheck.java |  2 +-
 .../apache/cassandra/service/StartupChecks.java    | 34 +++++++++++++++++++++-
 .../paxos/uncommitted/PaxosStateTracker.java       |  2 +-
 .../cassandra/service/StartupChecksTest.java       | 11 +++++--
 6 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 78456e28ad..c802607f42 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 4.2
+ * Warn on unknown directories found in system keyspace directory rather than 
kill node during startup checks (CASSANDRA-17777)
  * Log duplicate rows sharing a partition key found in verify and scrub 
(CASSANDRA-17789)
  * Add separate thread pool for Secondary Index building so it doesn't block 
compactions (CASSANDRA-17781)
  * Added JMX call to getSSTableCountPerTWCSBucket for TWCS (CASSANDRA-17774)
diff --git a/src/java/org/apache/cassandra/db/SystemKeyspace.java 
b/src/java/org/apache/cassandra/db/SystemKeyspace.java
index a1013e7955..c8c21b5e20 100644
--- a/src/java/org/apache/cassandra/db/SystemKeyspace.java
+++ b/src/java/org/apache/cassandra/db/SystemKeyspace.java
@@ -150,6 +150,7 @@ public final class SystemKeyspace
     public static final String BATCHES = "batches";
     public static final String PAXOS = "paxos";
     public static final String PAXOS_REPAIR_HISTORY = "paxos_repair_history";
+    public static final String PAXOS_REPAIR_STATE = "_paxos_repair_state";
     public static final String BUILT_INDEXES = "IndexInfo";
     public static final String LOCAL = "local";
     public static final String PEERS_V2 = "peers_v2";
@@ -185,6 +186,14 @@ public final class SystemKeyspace
     @Deprecated public static final String LEGACY_SIZE_ESTIMATES = 
"size_estimates";
     @Deprecated public static final String LEGACY_SSTABLE_ACTIVITY = 
"sstable_activity";
 
+    // Names of all tables that could have been a part of a system keyspace. 
Useful for pre-flight checks.
+    // For details, see CASSANDRA-17777
+    public static final Set<String> ALL_TABLE_NAMES = ImmutableSet.of(
+        BATCHES, PAXOS, PAXOS_REPAIR_HISTORY, PAXOS_REPAIR_STATE, 
BUILT_INDEXES, LOCAL, PEERS_V2, PEER_EVENTS_V2,
+        COMPACTION_HISTORY, SSTABLE_ACTIVITY_V2, TABLE_ESTIMATES, 
TABLE_ESTIMATES_TYPE_PRIMARY,
+        TABLE_ESTIMATES_TYPE_LOCAL_PRIMARY, AVAILABLE_RANGES_V2, 
TRANSFERRED_RANGES_V2, VIEW_BUILDS_IN_PROGRESS,
+        BUILT_VIEWS, PREPARED_STATEMENTS, REPAIRS, TOP_PARTITIONS, 
LEGACY_PEERS, LEGACY_PEER_EVENTS,
+        LEGACY_TRANSFERRED_RANGES, LEGACY_AVAILABLE_RANGES, 
LEGACY_SIZE_ESTIMATES, LEGACY_SSTABLE_ACTIVITY);
 
     public static final TableMetadata Batches =
         parse(BATCHES,
diff --git a/src/java/org/apache/cassandra/service/StartupCheck.java 
b/src/java/org/apache/cassandra/service/StartupCheck.java
index 331b381d2f..c3790e8e99 100644
--- a/src/java/org/apache/cassandra/service/StartupCheck.java
+++ b/src/java/org/apache/cassandra/service/StartupCheck.java
@@ -31,7 +31,7 @@ import 
org.apache.cassandra.service.StartupChecks.StartupCheckType;
  * misconfiguration of cluster_name in cassandra.yaml.
  *
  * The StartupChecks class manages a collection of these tests, which it 
executes
- * right at the beginning of the server settup process.
+ * right at the beginning of the server setup process.
  */
 public interface StartupCheck
 {
diff --git a/src/java/org/apache/cassandra/service/StartupChecks.java 
b/src/java/org/apache/cassandra/service/StartupChecks.java
index 2ab5381697..c313ac8f0c 100644
--- a/src/java/org/apache/cassandra/service/StartupChecks.java
+++ b/src/java/org/apache/cassandra/service/StartupChecks.java
@@ -165,7 +165,7 @@ public class StartupChecks
 
     /**
      * Run the configured tests and return a report detailing the results.
-     * @throws org.apache.cassandra.exceptions.StartupException if any test 
determines that the
+     * @throws StartupException if any test determines that the
      * system is not in an valid state to startup
      * @param options options to pass to respective checks for their 
configration
      */
@@ -571,6 +571,38 @@ public class StartupChecks
 
                 public FileVisitResult preVisitDirectory(Path dir, 
BasicFileAttributes attrs) throws IOException
                 {
+                    String[] nameParts = 
dir.toFile().getCanonicalPath().split(java.io.File.separator);
+                    if (nameParts.length >= 2)
+                    {
+                        String tablePart = nameParts[nameParts.length - 1];
+                        String ksPart = nameParts[nameParts.length - 2];
+
+                        if (tablePart.contains("-"))
+                            tablePart = tablePart.split("-")[0];
+
+                        // In very old versions of Cassandra, we wouldn't 
necessarily delete sstables from dropped system tables
+                        // which were removed in various major version 
upgrades (e.g system.Versions in 1.2)
+                        if 
(ksPart.equals(SchemaConstants.SYSTEM_KEYSPACE_NAME) && 
!SystemKeyspace.ALL_TABLE_NAMES.contains(tablePart))
+                        {
+                            // We can have snapshots of our system tables or 
snapshots created with a -t tag of "system" that would trigger
+                            // this potential warning, so we warn more softly 
in the case that it's probably a snapshot.
+                            if 
(dir.toFile().getCanonicalPath().contains("snapshot"))
+                            {
+                                logger.info("Found unknown system directory 
{}.{} at {} that contains the word snapshot. " +
+                                            "This may be left over from a 
previous version of Cassandra or may be normal. " +
+                                            " Consider removing after 
inspection if determined to be unnecessary.",
+                                            ksPart, tablePart, 
dir.toFile().getCanonicalPath());
+                            }
+                            else
+                            {
+                                logger.warn("Found unknown system directory 
{}.{} at {} - this is likely left over from a previous " +
+                                            "version of Cassandra and should 
be removed after inspection.",
+                                            ksPart, tablePart, 
dir.toFile().getCanonicalPath());
+                            }
+                            return FileVisitResult.SKIP_SUBTREE;
+                        }
+                    }
+
                     String name = dir.getFileName().toString();
                     return (name.equals(Directories.SNAPSHOT_SUBDIR)
                             || name.equals(Directories.BACKUPS_SUBDIR)
diff --git 
a/src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosStateTracker.java
 
b/src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosStateTracker.java
index d3594b3979..c869249350 100644
--- 
a/src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosStateTracker.java
+++ 
b/src/java/org/apache/cassandra/service/paxos/uncommitted/PaxosStateTracker.java
@@ -83,7 +83,7 @@ public class PaxosStateTracker
         return Boolean.getBoolean(TRUNCATE_BALLOT_METADATA_PROP);
     }
 
-    private static final String DIRECTORY = "system/_paxos_repair_state";
+    private static final String DIRECTORY = "system/" + 
SystemKeyspace.PAXOS_REPAIR_STATE;
 
     private final PaxosUncommittedTracker uncommitted;
     private final PaxosBallotTracker ballots;
diff --git a/test/unit/org/apache/cassandra/service/StartupChecksTest.java 
b/test/unit/org/apache/cassandra/service/StartupChecksTest.java
index 4a63fc1eb2..77c72530c4 100644
--- a/test/unit/org/apache/cassandra/service/StartupChecksTest.java
+++ b/test/unit/org/apache/cassandra/service/StartupChecksTest.java
@@ -36,13 +36,10 @@ import org.apache.cassandra.exceptions.StartupException;
 import org.apache.cassandra.service.DataResurrectionCheck.Heartbeat;
 import org.apache.cassandra.utils.Clock;
 
-import static java.time.Instant.ofEpochMilli;
 import static java.util.Collections.singletonList;
 import static org.apache.cassandra.io.util.FileUtils.createTempFile;
-import static org.apache.cassandra.io.util.FileUtils.write;
 import static 
org.apache.cassandra.service.DataResurrectionCheck.HEARTBEAT_FILE_CONFIG_PROPERTY;
 import static 
org.apache.cassandra.service.StartupChecks.StartupCheckType.check_data_resurrection;
-import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -115,6 +112,14 @@ public class StartupChecksTest
         Files.createDirectories(backupDir);
         copyInvalidLegacySSTables(backupDir);
         startupChecks.verify(options);
+
+        // and in the system directory as of CASSANDRA-17777
+        new File(backupDir).deleteRecursive();
+        File dataDir = new 
File(DatabaseDescriptor.getAllDataFileLocations()[0]);
+        Path systemDir = Paths.get(dataDir.absolutePath(), "system", 
"InvalidSystemDirectory");
+        Files.createDirectories(systemDir);
+        copyInvalidLegacySSTables(systemDir);
+        startupChecks.verify(options);
     }
 
     @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to