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

djoshi 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 02c6d65  Do not check cdc_raw_directory filesystem space if CDC 
disabled
02c6d65 is described below

commit 02c6d6540c6ab108b763a639146e74e9f8d0dd40
Author: Jon Meredith <[email protected]>
AuthorDate: Thu Apr 2 15:31:40 2020 -0600

    Do not check cdc_raw_directory filesystem space if CDC disabled
    
    On startup, applySimpleConfig checks disk space for cdc_raw_directory
    even if cdc_enabled=false.  The cdc_raw_directory could be computed
    automatically from the cassandra.storagedir property so if that
    has been deliberately set to an invalid directory (e.g. to force
    explicit configuration of storage paths) then the server will not
    start.
    
    Additionally this protects against an NPE while checking storage
    space if misconfigured.
    
    Patch by Jon Meredith; Reviewed by Dinesh Joshi for CASSANDRA-15688
---
 CHANGES.txt                                        |   1 +
 .../cassandra/config/DatabaseDescriptor.java       | 108 ++++++++++++---------
 .../cassandra/config/DatabaseDescriptorTest.java   |  22 +++++
 .../commitlog/CommitLogSegmentManagerCDCTest.java  |   1 +
 4 files changed, 86 insertions(+), 46 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index dc04d30..38fef18 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 4.0-alpha4
+ * Do not check cdc_raw_directory filesystem space if CDC disabled 
(CASSANDRA-15688)
  * Replace array iterators with get by index (CASSANDRA-15394)
  * Minimize BTree iterator allocations (CASSANDRA-15389)
  * Add client request size server metrics (CASSANDRA-15704)
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java 
b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index e6bee3a..d5794ae 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -79,6 +79,7 @@ import org.apache.commons.lang3.StringUtils;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static org.apache.cassandra.io.util.FileUtils.ONE_GB;
+import static org.apache.cassandra.io.util.FileUtils.ONE_MB;
 
 public class DatabaseDescriptor
 {
@@ -539,71 +540,60 @@ public class DatabaseDescriptor
             conf.native_transport_max_concurrent_requests_in_bytes_per_ip = 
Runtime.getRuntime().maxMemory() / 40;
         }
 
-        if (conf.cdc_raw_directory == null)
-        {
-            conf.cdc_raw_directory = storagedirFor("cdc_raw");
-        }
-
-        // Windows memory-mapped CommitLog files is incompatible with CDC as 
we hard-link files in cdc_raw. Confirm we don't have both enabled.
-        if (FBUtilities.isWindows && conf.cdc_enabled && 
conf.commitlog_compression == null)
-            throw new ConfigurationException("Cannot enable cdc on Windows 
with uncompressed commitlog.");
-
         if (conf.commitlog_total_space_in_mb == null)
         {
-            int preferredSize = 8192;
-            int minSize = 0;
+            final int preferredSizeInMB = 8192;
             try
             {
                 // use 1/4 of available space.  See discussion on #10013 and 
#10199
-                minSize = 
Ints.saturatedCast((guessFileStore(conf.commitlog_directory).getTotalSpace() / 
1048576) / 4);
+                final long totalSpaceInBytes = 
guessFileStore(conf.commitlog_directory).getTotalSpace();
+                conf.commitlog_total_space_in_mb = 
calculateDefaultSpaceInMB("commitlog",
+                                                                             
conf.commitlog_directory,
+                                                                             
"commitlog_total_space_in_mb",
+                                                                             
preferredSizeInMB,
+                                                                             
totalSpaceInBytes, 1, 4);
+
             }
             catch (IOException e)
             {
                 logger.debug("Error checking disk space", e);
-                throw new ConfigurationException(String.format("Unable to 
check disk space available to %s. Perhaps the Cassandra user does not have the 
necessary permissions",
+                throw new ConfigurationException(String.format("Unable to 
check disk space available to '%s'. Perhaps the Cassandra user does not have 
the necessary permissions",
                                                                
conf.commitlog_directory), e);
             }
-            if (minSize < preferredSize)
-            {
-                logger.warn("Small commitlog volume detected at {}; setting 
commitlog_total_space_in_mb to {}.  You can override this in cassandra.yaml",
-                            conf.commitlog_directory, minSize);
-                conf.commitlog_total_space_in_mb = minSize;
-            }
-            else
-            {
-                conf.commitlog_total_space_in_mb = preferredSize;
-            }
         }
 
-        if (conf.cdc_total_space_in_mb == 0)
+        if (conf.cdc_enabled)
         {
-            int preferredSize = 4096;
-            int minSize = 0;
-            try
-            {
-                // use 1/8th of available space.  See discussion on #10013 and 
#10199 on the CL, taking half that for CDC
-                minSize = 
Ints.saturatedCast((guessFileStore(conf.cdc_raw_directory).getTotalSpace() / 
1048576) / 8);
-            }
-            catch (IOException e)
-            {
-                logger.debug("Error checking disk space", e);
-                throw new ConfigurationException(String.format("Unable to 
check disk space available to %s. Perhaps the Cassandra user does not have the 
necessary permissions",
-                                                               
conf.cdc_raw_directory), e);
-            }
-            if (minSize < preferredSize)
+            // Windows memory-mapped CommitLog files is incompatible with CDC 
as we hard-link files in cdc_raw. Confirm we don't have both enabled.
+            if (FBUtilities.isWindows && conf.commitlog_compression == null)
+                throw new ConfigurationException("Cannot enable cdc on Windows 
with uncompressed commitlog.");
+
+            if (conf.cdc_raw_directory == null)
             {
-                logger.warn("Small cdc volume detected at {}; setting 
cdc_total_space_in_mb to {}.  You can override this in cassandra.yaml",
-                            conf.cdc_raw_directory, minSize);
-                conf.cdc_total_space_in_mb = minSize;
+                conf.cdc_raw_directory = storagedirFor("cdc_raw");
             }
-            else
+
+            if (conf.cdc_total_space_in_mb == 0)
             {
-                conf.cdc_total_space_in_mb = preferredSize;
+                final int preferredSizeInMB = 4096;
+                try
+                {
+                    // use 1/8th of available space.  See discussion on #10013 
and #10199 on the CL, taking half that for CDC
+                    final long totalSpaceInBytes = 
guessFileStore(conf.cdc_raw_directory).getTotalSpace();
+                    conf.cdc_total_space_in_mb = 
calculateDefaultSpaceInMB("cdc",
+                                                                           
conf.cdc_raw_directory,
+                                                                           
"cdc_total_space_in_mb",
+                                                                           
preferredSizeInMB,
+                                                                           
totalSpaceInBytes, 1, 8);
+                }
+                catch (IOException e)
+                {
+                    logger.debug("Error checking disk space", e);
+                    throw new ConfigurationException(String.format("Unable to 
check disk space available to '%s'. Perhaps the Cassandra user does not have 
the necessary permissions",
+                                                                   
conf.cdc_raw_directory), e);
+                }
             }
-        }
 
-        if (conf.cdc_enabled)
-        {
             logger.info("cdc_enabled is true. Starting casssandra node with 
Change-Data-Capture enabled.");
         }
 
@@ -873,6 +863,23 @@ public class DatabaseDescriptor
         return storagedir;
     }
 
+    static int calculateDefaultSpaceInMB(String type, String path, String 
setting, int preferredSizeInMB, long totalSpaceInBytes, long 
totalSpaceNumerator, long totalSpaceDenominator)
+    {
+        final long totalSizeInMB = totalSpaceInBytes / ONE_MB;
+        final int minSizeInMB = Ints.saturatedCast(totalSpaceNumerator * 
totalSizeInMB / totalSpaceDenominator);
+
+        if (minSizeInMB < preferredSizeInMB)
+        {
+            logger.warn("Small {} volume detected at '{}'; setting {} to {}.  
You can override this in cassandra.yaml",
+                        type, path, setting, minSizeInMB);
+            return minSizeInMB;
+        }
+        else
+        {
+            return preferredSizeInMB;
+        }
+    }
+
     public static void applyAddressConfig() throws ConfigurationException
     {
         applyAddressConfig(conf);
@@ -1153,9 +1160,17 @@ public class DatabaseDescriptor
             catch (IOException e)
             {
                 if (e instanceof NoSuchFileException)
+                {
                     path = path.getParent();
+                    if (path == null)
+                    {
+                        throw new ConfigurationException("Unable to find 
filesystem for '" + dir + "'.");
+                    }
+                }
                 else
+                {
                     throw e;
+                }
             }
         }
     }
@@ -2798,6 +2813,7 @@ public class DatabaseDescriptor
         return conf.cdc_enabled;
     }
 
+    @VisibleForTesting
     public static void setCDCEnabled(boolean cdc_enabled)
     {
         conf.cdc_enabled = cdc_enabled;
diff --git a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java 
b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
index dc380be..4a6a452 100644
--- a/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
+++ b/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
@@ -433,4 +433,26 @@ public class DatabaseDescriptorTest
             DatabaseDescriptor.setRepairSessionMaxTreeDepth(previousDepth);
         }
     }
+
+    @Test
+    public void testCalculateDefaultSpaceInMB()
+    {
+        // check prefered size is used for a small storage volume
+        int preferredInMB = 667;
+        int numerator = 2;
+        int denominator = 3;
+        int spaceInBytes = 999 * 1024 * 1024;
+
+        assertEquals(666, // total size is less than preferred, so return 
lower limit
+                     DatabaseDescriptor.calculateDefaultSpaceInMB("type", 
"/path", "setting_name", preferredInMB, spaceInBytes, numerator, denominator));
+
+        // check preferred size is used for a small storage volume
+        preferredInMB = 100;
+        numerator = 1;
+        denominator = 3;
+        spaceInBytes = 999 * 1024 * 1024;
+
+        assertEquals(100, // total size is more than preferred so keep the 
configured limit
+                     DatabaseDescriptor.calculateDefaultSpaceInMB("type", 
"/path", "setting_name", preferredInMB, spaceInBytes, numerator, denominator));
+    }
 }
diff --git 
a/test/unit/org/apache/cassandra/db/commitlog/CommitLogSegmentManagerCDCTest.java
 
b/test/unit/org/apache/cassandra/db/commitlog/CommitLogSegmentManagerCDCTest.java
index 8c0647c..4128b71 100644
--- 
a/test/unit/org/apache/cassandra/db/commitlog/CommitLogSegmentManagerCDCTest.java
+++ 
b/test/unit/org/apache/cassandra/db/commitlog/CommitLogSegmentManagerCDCTest.java
@@ -46,6 +46,7 @@ public class CommitLogSegmentManagerCDCTest extends CQLTester
     public static void setUpClass()
     {
         DatabaseDescriptor.setCDCEnabled(true);
+        DatabaseDescriptor.setCDCSpaceInMB(1024);
         CQLTester.setUpClass();
     }
 


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

Reply via email to