Repository: cassandra Updated Branches: refs/heads/cassandra-2.2 8bc32ba08 -> f2b66166a refs/heads/cassandra-3.0 e805f1466 -> 3d5742814 refs/heads/trunk d1ca74503 -> 05caec77c
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/trunk Commit: 8bc32ba081d7da6b2f39b500de09ef1a4c44ac9d Parents: c5158e5 Author: Jonathan Ellis <[email protected]> Authored: Fri Aug 28 16:53:03 2015 -0500 Committer: Jonathan Ellis <[email protected]> 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("."))
