mirror of https://github.com/apache/cassandra
ensure that directory is selected for compaction
patch by Aaron Morton; reviewed by Pavel Yaskevich for CASSANDRA-3985
This commit is contained in:
parent
5a3d4c14b2
commit
fbdf7b03c7
|
|
@ -10,6 +10,7 @@
|
|||
* don't change manifest level for cleanup, scrub, and upgradesstables
|
||||
operations under LeveledCompactionStrategy (CASSANDRA-3989)
|
||||
* fix race leading to super columns assertion failure (CASSANDRA-3957)
|
||||
* ensure that directory is selected for compaction (CASSANDRA-3985)
|
||||
|
||||
|
||||
1.0.8
|
||||
|
|
|
|||
|
|
@ -63,8 +63,6 @@ public class DatabaseDescriptor
|
|||
private static InetAddress broadcastAddress;
|
||||
private static InetAddress rpcAddress;
|
||||
private static SeedProvider seedProvider;
|
||||
/* Current index into the above list of directories */
|
||||
private static int currentIndex = 0;
|
||||
|
||||
/* Hashing strategy Random or OPHF */
|
||||
private static IPartitioner partitioner;
|
||||
|
|
@ -741,12 +739,6 @@ public class DatabaseDescriptor
|
|||
return tableLocations;
|
||||
}
|
||||
|
||||
public synchronized static String getNextAvailableDataLocation()
|
||||
{
|
||||
String dataFileDirectory = conf.data_file_directories[currentIndex];
|
||||
currentIndex = (currentIndex + 1) % conf.data_file_directories.length;
|
||||
return dataFileDirectory;
|
||||
}
|
||||
|
||||
public static String getCommitLogLocation()
|
||||
{
|
||||
|
|
@ -763,41 +755,57 @@ public class DatabaseDescriptor
|
|||
return Collections.unmodifiableSet(new HashSet(seedProvider.getSeeds()));
|
||||
}
|
||||
|
||||
public synchronized static String getDataFileLocationForTable(String table, long expectedCompactedFileSize)
|
||||
{
|
||||
return getDataFileLocationForTable(table, expectedCompactedFileSize, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through all the disks to see which disk has the max free space
|
||||
* return the disk with max free space for compactions. If the size of the expected
|
||||
* compacted file is greater than the max disk space available return null, we cannot
|
||||
* do compaction in this case.
|
||||
*
|
||||
* @param table name of the table.
|
||||
* @param expectedCompactedSize expected file size in bytes.
|
||||
* @param ensureFreeSpace Flag if the function should ensure enough free space exists for the expected file size.
|
||||
* If False and there is not enough free space a warning is logged, and the dir with the most space is returned.
|
||||
*/
|
||||
public static String getDataFileLocationForTable(String table, long expectedCompactedFileSize)
|
||||
public synchronized static String getDataFileLocationForTable(String table, long expectedCompactedFileSize, boolean ensureFreeSpace)
|
||||
{
|
||||
long maxFreeDisk = 0;
|
||||
int maxDiskIndex = 0;
|
||||
String dataFileDirectory = null;
|
||||
String[] dataDirectoryForTable = getAllDataFileLocationsForTable(table);
|
||||
long maxFreeDisk = 0;
|
||||
int maxDiskIndex = 0;
|
||||
String dataFileDirectory = null;
|
||||
String[] dataDirectoryForTable = getAllDataFileLocationsForTable(table);
|
||||
|
||||
for ( int i = 0 ; i < dataDirectoryForTable.length ; i++ )
|
||||
{
|
||||
File f = new File(dataDirectoryForTable[i]);
|
||||
if( maxFreeDisk < f.getUsableSpace())
|
||||
for (int i = 0; i < dataDirectoryForTable.length; i++)
|
||||
{
|
||||
maxFreeDisk = f.getUsableSpace();
|
||||
maxDiskIndex = i;
|
||||
File f = new File(dataDirectoryForTable[i]);
|
||||
|
||||
if (maxFreeDisk < f.getUsableSpace())
|
||||
{
|
||||
maxFreeDisk = f.getUsableSpace();
|
||||
maxDiskIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("expected data files size is {}; largest free partition has {} bytes free",
|
||||
expectedCompactedFileSize, maxFreeDisk);
|
||||
// Load factor of 0.9 we do not want to use the entire disk that is too risky.
|
||||
maxFreeDisk = (long)(0.9 * maxFreeDisk);
|
||||
if( expectedCompactedFileSize < maxFreeDisk )
|
||||
{
|
||||
dataFileDirectory = dataDirectoryForTable[maxDiskIndex];
|
||||
currentIndex = (maxDiskIndex + 1 )%dataDirectoryForTable.length ;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentIndex = maxDiskIndex;
|
||||
}
|
||||
expectedCompactedFileSize,
|
||||
maxFreeDisk);
|
||||
|
||||
// Load factor of 0.9 we do not want to use the entire disk that is too risky.
|
||||
maxFreeDisk = (long) (0.9 * maxFreeDisk);
|
||||
if (!ensureFreeSpace || expectedCompactedFileSize < maxFreeDisk)
|
||||
{
|
||||
dataFileDirectory = dataDirectoryForTable[maxDiskIndex];
|
||||
|
||||
if (expectedCompactedFileSize >= maxFreeDisk)
|
||||
logger.warn(String.format("Data file location %s only has %d free, expected size is %d",
|
||||
dataFileDirectory,
|
||||
maxFreeDisk,
|
||||
expectedCompactedFileSize));
|
||||
}
|
||||
|
||||
return dataFileDirectory;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -556,7 +556,12 @@ public class Table
|
|||
|
||||
public String getDataFileLocation(long expectedSize)
|
||||
{
|
||||
String path = DatabaseDescriptor.getDataFileLocationForTable(name, expectedSize);
|
||||
return getDataFileLocation(expectedSize, true);
|
||||
}
|
||||
|
||||
public String getDataFileLocation(long expectedSize, boolean ensureFreeSpace)
|
||||
{
|
||||
String path = DatabaseDescriptor.getDataFileLocationForTable(name, expectedSize, ensureFreeSpace);
|
||||
// Requesting GC has a chance to free space only if we're using mmap and a non SUN jvm
|
||||
if (path == null
|
||||
&& (DatabaseDescriptor.getDiskAccessMode() == Config.DiskAccessMode.mmap || DatabaseDescriptor.getIndexAccessMode() == Config.DiskAccessMode.mmap)
|
||||
|
|
@ -574,7 +579,7 @@ public class Table
|
|||
{
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
path = DatabaseDescriptor.getDataFileLocationForTable(name, expectedSize);
|
||||
path = DatabaseDescriptor.getDataFileLocationForTable(name, expectedSize, ensureFreeSpace);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,21 +77,20 @@ public class CompactionTask extends AbstractCompactionTask
|
|||
return 0;
|
||||
|
||||
if (compactionFileLocation == null)
|
||||
compactionFileLocation = cfs.table.getDataFileLocation(cfs.getExpectedCompactedFileSize(toCompact));
|
||||
if (partialCompactionsAcceptable())
|
||||
compactionFileLocation = cfs.table.getDataFileLocation(cfs.getExpectedCompactedFileSize(toCompact), ensureFreeSpace());
|
||||
|
||||
if (compactionFileLocation == null && partialCompactionsAcceptable())
|
||||
{
|
||||
// If the compaction file path is null that means we have no space left for this compaction.
|
||||
// Try again w/o the largest one.
|
||||
if (compactionFileLocation == null)
|
||||
while (compactionFileLocation == null && toCompact.size() > 1)
|
||||
{
|
||||
while (compactionFileLocation == null && toCompact.size() > 1)
|
||||
{
|
||||
logger.warn("insufficient space to compact all requested files " + StringUtils.join(toCompact, ", "));
|
||||
// Note that we have removed files that are still marked as compacting. This suboptimal but ok since the caller will unmark all
|
||||
// the sstables at the end.
|
||||
toCompact.remove(cfs.getMaxSizeFile(toCompact));
|
||||
compactionFileLocation = cfs.table.getDataFileLocation(cfs.getExpectedCompactedFileSize(toCompact));
|
||||
}
|
||||
logger.warn("insufficient space to compact all requested files " + StringUtils.join(toCompact, ", "));
|
||||
// Note that we have removed files that are still marked as compacting.
|
||||
// This suboptimal but ok since the caller will unmark all the sstables at the end.
|
||||
toCompact.remove(cfs.getMaxSizeFile(toCompact));
|
||||
compactionFileLocation = cfs.table.getDataFileLocation(cfs.getExpectedCompactedFileSize(toCompact),
|
||||
ensureFreeSpace());
|
||||
}
|
||||
|
||||
if (compactionFileLocation == null)
|
||||
|
|
@ -100,6 +99,7 @@ public class CompactionTask extends AbstractCompactionTask
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
assert compactionFileLocation != null;
|
||||
|
||||
if (DatabaseDescriptor.isSnapshotBeforeCompaction())
|
||||
cfs.snapshotWithoutFlush(System.currentTimeMillis() + "-" + "compact-" + cfs.columnFamily);
|
||||
|
|
@ -231,6 +231,11 @@ public class CompactionTask extends AbstractCompactionTask
|
|||
return !isUserDefined;
|
||||
}
|
||||
|
||||
protected boolean ensureFreeSpace()
|
||||
{
|
||||
return !isUserDefined;
|
||||
}
|
||||
|
||||
//extensibility point for other strategies that may want to limit the upper bounds of the sstable segment size
|
||||
protected boolean newSSTableSegmentThresholdReached(SSTableWriter writer, long position)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue