You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2015/08/29 00:04:03 UTC

[1/3] cassandra git commit: Fall back to 1/4 commitlog volume for commitlog_total_space on small disks reviewed by aweisberg for CASSANDRA-10199

Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.2 c5158e53e -> 8bc32ba08
  refs/heads/cassandra-3.0 56ec3c86d -> e805f1466


Fall back to 1/4 commitlog volume for commitlog_total_space on small disks
reviewed by aweisberg for CASSANDRA-10199


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/8bc32ba0
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/8bc32ba0
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/8bc32ba0

Branch: refs/heads/cassandra-2.2
Commit: 8bc32ba081d7da6b2f39b500de09ef1a4c44ac9d
Parents: c5158e5
Author: Jonathan Ellis <jb...@apache.org>
Authored: Fri Aug 28 16:53:03 2015 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Fri Aug 28 16:55:56 2015 -0500

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 NEWS.txt                                        |  6 ++
 conf/cassandra.yaml                             |  4 +-
 .../cassandra/config/DatabaseDescriptor.java    | 72 +++++++++++++++++++-
 4 files changed, 80 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index c215a50..7aec3bc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,6 @@
 2.2.1
+ * Fall back to 1/4 commitlog volume for commitlog_total_space on small disks
+   (CASSANDRA-10199)
  * Fix race during construction of commit log (CASSANDRA-10049)
  * Fix LeveledCompactionStrategyTest (CASSANDRA-9757)
  * Fix broken UnbufferedDataOutputStreamPlus.writeUTF (CASSANDRA-10203)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index e8db40d..fd952e2 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -26,6 +26,12 @@ New features
 ------------
    - COUNT(*) and COUNT(1) can be selected with other columns or functions
 
+Changed Defaults
+----------------
+   - commitlog_total_space_in_mb will use the smaller of 8192, and 1/4
+     of the total space of the commitlog volume. (Before: always used
+     8192)
+
 
 2.2
 ===

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/conf/cassandra.yaml
----------------------------------------------------------------------
diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
index 174f7db..4ff7afb 100644
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@ -362,7 +362,9 @@ memtable_allocation_type: heap_buffers
 # in the oldest segment and remove it.  So a small total commitlog space
 # will tend to cause more flush activity on less-active columnfamilies.
 #
-# The default value is 8192.
+# The default value is the smaller of 8192, and 1/4 of the total space
+# of the commitlog volume.
+#
 # commitlog_total_space_in_mb: 8192
 
 # This sets the amount of memtable flush writer threads.  These will

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index e7c76ff..b7e3eaa 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -20,10 +20,16 @@ package org.apache.cassandra.config;
 import java.io.File;
 import java.io.IOException;
 import java.net.*;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.*;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.primitives.Ints;
 import com.google.common.primitives.Longs;
 
 import org.slf4j.Logger;
@@ -288,9 +294,6 @@ public class DatabaseDescriptor
             logger.debug("Syncing log with a period of {}", conf.commitlog_sync_period_in_ms);
         }
 
-        if (conf.commitlog_total_space_in_mb == null)
-            conf.commitlog_total_space_in_mb = 8192;
-
         /* evaluate the DiskAccessMode Config directive, which also affects indexAccessMode selection */
         if (conf.disk_access_mode == Config.DiskAccessMode.auto)
         {
@@ -483,6 +486,34 @@ public class DatabaseDescriptor
                 throw new ConfigurationException("commitlog_directory is missing and -Dcassandra.storagedir is not set", false);
             conf.commitlog_directory += File.separator + "commitlog";
         }
+
+        if (conf.commitlog_total_space_in_mb == null)
+        {
+            int preferredSize = 8192;
+            int minSize = 0;
+            try
+            {
+                // use 1/4 of available space.  See discussion on #10013 and #10199
+                minSize = Ints.checkedCast((guessFileStore(conf.commitlog_directory).getTotalSpace() / 1048576) / 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",
+                                                               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.saved_caches_directory == null)
         {
             conf.saved_caches_directory = System.getProperty("cassandra.storagedir", null);
@@ -498,6 +529,7 @@ public class DatabaseDescriptor
             conf.data_file_directories = new String[]{ defaultDataDir + File.separator + "data" };
         }
 
+        long dataFreeBytes = 0;
         /* data file and commit log directories. they get created later, when they're needed. */
         for (String datadir : conf.data_file_directories)
         {
@@ -505,7 +537,22 @@ public class DatabaseDescriptor
                 throw new ConfigurationException("commitlog_directory must not be the same as any data_file_directories", false);
             if (datadir.equals(conf.saved_caches_directory))
                 throw new ConfigurationException("saved_caches_directory must not be the same as any data_file_directories", false);
+
+            try
+            {
+                dataFreeBytes += guessFileStore(datadir).getUnallocatedSpace();
+            }
+            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",
+                                                               datadir), e);
+            }
         }
+        if (dataFreeBytes < 64L * 1024 * 1048576) // 64 GB
+            logger.warn("Only {} MB free across all data volumes. Consider adding more capacity to your cluster or removing obsolete snapshots",
+                        dataFreeBytes / 1048576);
+
 
         if (conf.commitlog_directory.equals(conf.saved_caches_directory))
             throw new ConfigurationException("saved_caches_directory must not be the same as the commitlog_directory", false);
@@ -608,6 +655,25 @@ public class DatabaseDescriptor
             throw new ConfigurationException("The seed provider lists no seeds.", false);
     }
 
+    private static FileStore guessFileStore(String dir) throws IOException
+    {
+        Path path = Paths.get(dir);
+        while (true)
+        {
+            try
+            {
+                return Files.getFileStore(path);
+            }
+            catch (IOException e)
+            {
+                if (e instanceof NoSuchFileException)
+                    path = path.getParent();
+                else
+                    throw e;
+            }
+        }
+    }
+
     private static IEndpointSnitch createEndpointSnitch(String snitchClassName) throws ConfigurationException
     {
         if (!snitchClassName.contains("."))


[3/3] cassandra git commit: merge from 2.2

Posted by jb...@apache.org.
merge from 2.2


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e805f146
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e805f146
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e805f146

Branch: refs/heads/cassandra-3.0
Commit: e805f1466b8589ad79bafe1f9ad16c4206525036
Parents: 56ec3c8 8bc32ba
Author: Jonathan Ellis <jb...@apache.org>
Authored: Fri Aug 28 17:01:36 2015 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Fri Aug 28 17:01:36 2015 -0500

----------------------------------------------------------------------
 CHANGES.txt                                     |  3 +
 NEWS.txt                                        |  6 ++
 conf/cassandra.yaml                             |  4 +-
 .../cassandra/config/DatabaseDescriptor.java    | 72 +++++++++++++++++++-
 4 files changed, 81 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e805f146/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index a2cf9c8,7aec3bc..bf40dd2
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,50 -1,11 +1,53 @@@
 -2.2.1
 +3.0.0-beta2
 + * Fix Materialized View builder when adding multiple MVs (CASSANDRA-10156)
 + * Choose better poolingOptions for protocol v4 in cassandra-stress (CASSANDRA-10182)
 + * Fix LWW bug affecting Materialized Views (CASSANDRA-10197)
 + * Ensures frozen sets and maps are always sorted (CASSANDRA-10162)
 + * Don't deadlock when flushing CFS backed custom indexes (CASSANDRA-10181)
 + * Fix double flushing of secondary index tables (CASSANDRA-10180)
 + * Fix incorrect handling of range tombstones in thrift (CASSANDRA-10046)
 + * Only use batchlog when paired materialized view replica is remote (CASSANDRA-10061)
 + * Reuse TemporalRow when updating multiple MaterializedViews (CASSANDRA-10060)
 + * Validate gc_grace_seconds for batchlog writes and MVs (CASSANDRA-9917)
 + * Fix sstablerepairedset (CASSANDRA-10132)
 +Merged from 2.2:
+  * Fall back to 1/4 commitlog volume for commitlog_total_space on small disks
+    (CASSANDRA-10199)
+  * Fix race during construction of commit log (CASSANDRA-10049)
   * Fix LeveledCompactionStrategyTest (CASSANDRA-9757)
   * Fix broken UnbufferedDataOutputStreamPlus.writeUTF (CASSANDRA-10203)
 + * (cqlsh) default load-from-file encoding to utf-8 (CASSANDRA-9898)
 + * Avoid returning Permission.NONE when failing to query users table (CASSANDRA-10168)
   * (cqlsh) add CLEAR command (CASSANDRA-10086)
   * Support string literals as Role names for compatibility (CASSANDRA-10135)
 +Merged from 2.1:
 + * Change streaming_socket_timeout_in_ms default to 1 hour (CASSANDRA-8611)
 + * (cqlsh) update list of CQL keywords (CASSANDRA-9232)
 +
 +
 +3.0.0-beta1
 + * Redesign secondary index API (CASSANDRA-9459, 7771, 9041)
 + * Fix throwing ReadFailure instead of ReadTimeout on range queries (CASSANDRA-10125)
 + * Rewrite hinted handoff (CASSANDRA-6230)
 + * Fix query on static compact tables (CASSANDRA-10093)
 + * Fix race during construction of commit log (CASSANDRA-10049)
 + * Add option to only purge repaired tombstones (CASSANDRA-6434)
 + * Change authorization handling for MVs (CASSANDRA-9927)
 + * Add custom JMX enabled executor for UDF sandbox (CASSANDRA-10026)
 + * Fix row deletion bug for Materialized Views (CASSANDRA-10014)
 + * Support mixed-version clusters with Cassandra 2.1 and 2.2 (CASSANDRA-9704)
 + * Fix multiple slices on RowSearchers (CASSANDRA-10002)
 + * Fix bug in merging of collections (CASSANDRA-10001)
 + * Optimize batchlog replay to avoid full scans (CASSANDRA-7237)
 + * Repair improvements when using vnodes (CASSANDRA-5220)
 + * Disable scripted UDFs by default (CASSANDRA-9889)
 + * Bytecode inspection for Java-UDFs (CASSANDRA-9890)
 + * Use byte to serialize MT hash length (CASSANDRA-9792)
 + * Replace usage of Adler32 with CRC32 (CASSANDRA-8684)
 + * Fix migration to new format from 2.1 SSTable (CASSANDRA-10006)
 + * SequentialWriter should extend BufferedDataOutputStreamPlus (CASSANDRA-9500)
 + * Use the same repairedAt timestamp within incremental repair session (CASSANDRA-9111)
 +Merged from 2.2:
   * Allow count(*) and count(1) to be use as normal aggregation (CASSANDRA-10114)
   * An NPE is thrown if the column name is unknown for an IN relation (CASSANDRA-10043)
   * Apply commit_failure_policy to more errors on startup (CASSANDRA-9749)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e805f146/NEWS.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e805f146/conf/cassandra.yaml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e805f146/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 01455ac,b7e3eaa..ba283b4
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@@ -483,14 -487,33 +487,41 @@@ public class DatabaseDescripto
              conf.commitlog_directory += File.separator + "commitlog";
          }
  
 +        if (conf.hints_directory == null)
 +        {
 +            conf.hints_directory = System.getProperty("cassandra.storagedir", null);
 +            if (conf.hints_directory == null)
 +                throw new ConfigurationException("hints_directory is missing and -Dcassandra.storagedir is not set", false);
 +            conf.hints_directory += File.separator + "hints";
 +        }
 +
+         if (conf.commitlog_total_space_in_mb == null)
+         {
+             int preferredSize = 8192;
+             int minSize = 0;
+             try
+             {
+                 // use 1/4 of available space.  See discussion on #10013 and #10199
+                 minSize = Ints.checkedCast((guessFileStore(conf.commitlog_directory).getTotalSpace() / 1048576) / 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",
+                                                                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.saved_caches_directory == null)
          {
              conf.saved_caches_directory = System.getProperty("cassandra.storagedir", null);
@@@ -511,11 -535,24 +543,26 @@@
          {
              if (datadir.equals(conf.commitlog_directory))
                  throw new ConfigurationException("commitlog_directory must not be the same as any data_file_directories", false);
 +            if (datadir.equals(conf.hints_directory))
 +                throw new ConfigurationException("hints_directory must not be the same as any data_file_directories", false);
              if (datadir.equals(conf.saved_caches_directory))
                  throw new ConfigurationException("saved_caches_directory must not be the same as any data_file_directories", false);
+ 
+             try
+             {
+                 dataFreeBytes += guessFileStore(datadir).getUnallocatedSpace();
+             }
+             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",
+                                                                datadir), e);
+             }
          }
+         if (dataFreeBytes < 64L * 1024 * 1048576) // 64 GB
+             logger.warn("Only {} MB free across all data volumes. Consider adding more capacity to your cluster or removing obsolete snapshots",
+                         dataFreeBytes / 1048576);
+ 
  
          if (conf.commitlog_directory.equals(conf.saved_caches_directory))
              throw new ConfigurationException("saved_caches_directory must not be the same as the commitlog_directory", false);
@@@ -620,21 -653,27 +667,40 @@@
          }
          if (seedProvider.getSeeds().size() == 0)
              throw new ConfigurationException("The seed provider lists no seeds.", false);
 +
 +        if (conf.user_defined_function_fail_timeout < 0)
 +            throw new ConfigurationException("user_defined_function_fail_timeout must not be negative", false);
 +        if (conf.user_defined_function_warn_timeout < 0)
 +            throw new ConfigurationException("user_defined_function_warn_timeout must not be negative", false);
 +
 +        if (conf.user_defined_function_fail_timeout < conf.user_defined_function_warn_timeout)
 +            throw new ConfigurationException("user_defined_function_warn_timeout must less than user_defined_function_fail_timeout", false);
 +
 +        if (conf.max_mutation_size_in_kb == null)
 +            conf.max_mutation_size_in_kb = conf.commitlog_segment_size_in_mb * 1024 / 2;
 +        else if (conf.commitlog_segment_size_in_mb * 1024 < 2 * conf.max_mutation_size_in_kb)
 +            throw new ConfigurationException("commitlog_segment_size_in_mb must be at least twice the size of max_mutation_size_in_kb / 1024", false);
      }
  
+     private static FileStore guessFileStore(String dir) throws IOException
+     {
+         Path path = Paths.get(dir);
+         while (true)
+         {
+             try
+             {
+                 return Files.getFileStore(path);
+             }
+             catch (IOException e)
+             {
+                 if (e instanceof NoSuchFileException)
+                     path = path.getParent();
+                 else
+                     throw e;
+             }
+         }
+     }
+ 
      private static IEndpointSnitch createEndpointSnitch(String snitchClassName) throws ConfigurationException
      {
          if (!snitchClassName.contains("."))


[2/3] cassandra git commit: Fall back to 1/4 commitlog volume for commitlog_total_space on small disks reviewed by aweisberg for CASSANDRA-10199

Posted by jb...@apache.org.
Fall back to 1/4 commitlog volume for commitlog_total_space on small disks
reviewed by aweisberg for CASSANDRA-10199


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/8bc32ba0
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/8bc32ba0
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/8bc32ba0

Branch: refs/heads/cassandra-3.0
Commit: 8bc32ba081d7da6b2f39b500de09ef1a4c44ac9d
Parents: c5158e5
Author: Jonathan Ellis <jb...@apache.org>
Authored: Fri Aug 28 16:53:03 2015 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Fri Aug 28 16:55:56 2015 -0500

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 NEWS.txt                                        |  6 ++
 conf/cassandra.yaml                             |  4 +-
 .../cassandra/config/DatabaseDescriptor.java    | 72 +++++++++++++++++++-
 4 files changed, 80 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index c215a50..7aec3bc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,6 @@
 2.2.1
+ * Fall back to 1/4 commitlog volume for commitlog_total_space on small disks
+   (CASSANDRA-10199)
  * Fix race during construction of commit log (CASSANDRA-10049)
  * Fix LeveledCompactionStrategyTest (CASSANDRA-9757)
  * Fix broken UnbufferedDataOutputStreamPlus.writeUTF (CASSANDRA-10203)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index e8db40d..fd952e2 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -26,6 +26,12 @@ New features
 ------------
    - COUNT(*) and COUNT(1) can be selected with other columns or functions
 
+Changed Defaults
+----------------
+   - commitlog_total_space_in_mb will use the smaller of 8192, and 1/4
+     of the total space of the commitlog volume. (Before: always used
+     8192)
+
 
 2.2
 ===

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/conf/cassandra.yaml
----------------------------------------------------------------------
diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
index 174f7db..4ff7afb 100644
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@ -362,7 +362,9 @@ memtable_allocation_type: heap_buffers
 # in the oldest segment and remove it.  So a small total commitlog space
 # will tend to cause more flush activity on less-active columnfamilies.
 #
-# The default value is 8192.
+# The default value is the smaller of 8192, and 1/4 of the total space
+# of the commitlog volume.
+#
 # commitlog_total_space_in_mb: 8192
 
 # This sets the amount of memtable flush writer threads.  These will

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8bc32ba0/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index e7c76ff..b7e3eaa 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -20,10 +20,16 @@ package org.apache.cassandra.config;
 import java.io.File;
 import java.io.IOException;
 import java.net.*;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.*;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.primitives.Ints;
 import com.google.common.primitives.Longs;
 
 import org.slf4j.Logger;
@@ -288,9 +294,6 @@ public class DatabaseDescriptor
             logger.debug("Syncing log with a period of {}", conf.commitlog_sync_period_in_ms);
         }
 
-        if (conf.commitlog_total_space_in_mb == null)
-            conf.commitlog_total_space_in_mb = 8192;
-
         /* evaluate the DiskAccessMode Config directive, which also affects indexAccessMode selection */
         if (conf.disk_access_mode == Config.DiskAccessMode.auto)
         {
@@ -483,6 +486,34 @@ public class DatabaseDescriptor
                 throw new ConfigurationException("commitlog_directory is missing and -Dcassandra.storagedir is not set", false);
             conf.commitlog_directory += File.separator + "commitlog";
         }
+
+        if (conf.commitlog_total_space_in_mb == null)
+        {
+            int preferredSize = 8192;
+            int minSize = 0;
+            try
+            {
+                // use 1/4 of available space.  See discussion on #10013 and #10199
+                minSize = Ints.checkedCast((guessFileStore(conf.commitlog_directory).getTotalSpace() / 1048576) / 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",
+                                                               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.saved_caches_directory == null)
         {
             conf.saved_caches_directory = System.getProperty("cassandra.storagedir", null);
@@ -498,6 +529,7 @@ public class DatabaseDescriptor
             conf.data_file_directories = new String[]{ defaultDataDir + File.separator + "data" };
         }
 
+        long dataFreeBytes = 0;
         /* data file and commit log directories. they get created later, when they're needed. */
         for (String datadir : conf.data_file_directories)
         {
@@ -505,7 +537,22 @@ public class DatabaseDescriptor
                 throw new ConfigurationException("commitlog_directory must not be the same as any data_file_directories", false);
             if (datadir.equals(conf.saved_caches_directory))
                 throw new ConfigurationException("saved_caches_directory must not be the same as any data_file_directories", false);
+
+            try
+            {
+                dataFreeBytes += guessFileStore(datadir).getUnallocatedSpace();
+            }
+            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",
+                                                               datadir), e);
+            }
         }
+        if (dataFreeBytes < 64L * 1024 * 1048576) // 64 GB
+            logger.warn("Only {} MB free across all data volumes. Consider adding more capacity to your cluster or removing obsolete snapshots",
+                        dataFreeBytes / 1048576);
+
 
         if (conf.commitlog_directory.equals(conf.saved_caches_directory))
             throw new ConfigurationException("saved_caches_directory must not be the same as the commitlog_directory", false);
@@ -608,6 +655,25 @@ public class DatabaseDescriptor
             throw new ConfigurationException("The seed provider lists no seeds.", false);
     }
 
+    private static FileStore guessFileStore(String dir) throws IOException
+    {
+        Path path = Paths.get(dir);
+        while (true)
+        {
+            try
+            {
+                return Files.getFileStore(path);
+            }
+            catch (IOException e)
+            {
+                if (e instanceof NoSuchFileException)
+                    path = path.getParent();
+                else
+                    throw e;
+            }
+        }
+    }
+
     private static IEndpointSnitch createEndpointSnitch(String snitchClassName) throws ConfigurationException
     {
         if (!snitchClassName.contains("."))