Author: jbellis
Date: Thu Feb 4 20:04:20 2010
New Revision: 906631
URL: http://svn.apache.org/viewvc?rev=906631&view=rev
Log:
only gc if there are undeleted sstables that gc-ing could free
patch by jbellis; tested by Brandon Williams for CASSANDRA-724
Modified:
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableDeletingReference.java
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableReader.java
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableTracker.java
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
Modified:
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=906631&r1=906630&r2=906631&view=diff
==============================================================================
---
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
(original)
+++
incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
Thu Feb 4 20:04:20 2010
@@ -1144,24 +1144,19 @@
}
}
+ public boolean hasUnreclaimedSpace()
+ {
+ return ssTables_.getLiveSize() < ssTables_.getTotalSize();
+ }
+
public long getTotalDiskSpaceUsed()
{
- long n = 0;
- for (File file : files())
- {
- n += file.length();
- }
- return n;
+ return ssTables_.getTotalSize();
}
public long getLiveDiskSpaceUsed()
{
- long n = 0;
- for (SSTableReader sstable : ssTables_)
- {
- n += sstable.bytesOnDisk();
- }
- return n;
+ return ssTables_.getLiveSize();
}
public int getLiveSSTableCount()
Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java?rev=906631&r1=906630&r2=906631&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
(original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java Thu
Feb 4 20:04:20 2010
@@ -208,7 +208,7 @@
return tableMetadata.getColumnFamilies();
}
- Collection<ColumnFamilyStore> getColumnFamilyStores()
+ public Collection<ColumnFamilyStore> getColumnFamilyStores()
{
return Collections.unmodifiableCollection(columnFamilyStores.values());
}
@@ -479,7 +479,7 @@
if (path == null)
{
// retry after GCing to force unmap of compacted SSTables so they
can be deleted
- StorageService.requestGC();
+ StorageService.instance.requestGC();
try
{
Thread.sleep(SSTableDeletingReference.RETRY_DELAY * 2);
Modified:
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableDeletingReference.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableDeletingReference.java?rev=906631&r1=906630&r2=906631&view=diff
==============================================================================
---
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableDeletingReference.java
(original)
+++
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableDeletingReference.java
Thu Feb 4 20:04:20 2010
@@ -1,6 +1,7 @@
package org.apache.cassandra.io;
import java.io.File;
+import java.io.IOError;
import java.io.IOException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
@@ -9,6 +10,8 @@
import org.apache.log4j.Logger;
+import org.apache.cassandra.io.util.FileUtils;
+
public class SSTableDeletingReference extends PhantomReference<SSTableReader>
{
private static final Logger logger =
Logger.getLogger(SSTableDeletingReference.class);
@@ -16,13 +19,17 @@
private static final Timer timer = new Timer("SSTABLE-CLEANUP-TIMER");
public static final int RETRY_DELAY = 10000;
+ private final SSTableTracker tracker;
public final String path;
+ private final long size;
private boolean deleteOnCleanup;
- SSTableDeletingReference(SSTableReader referent, ReferenceQueue<? super
SSTableReader> q)
+ SSTableDeletingReference(SSTableTracker tracker, SSTableReader referent,
ReferenceQueue<? super SSTableReader> q)
{
super(referent, q);
+ this.tracker = tracker;
this.path = referent.path;
+ this.size = referent.bytesOnDisk();
}
public void deleteOnCleanup()
@@ -62,10 +69,18 @@
throw new RuntimeException("Unable to delete " + path);
}
}
+ try
+ {
+ FileUtils.deleteWithConfirm(new
File(SSTable.indexFilename(path)));
+ FileUtils.deleteWithConfirm(new
File(SSTable.filterFilename(path)));
+ FileUtils.deleteWithConfirm(new
File(SSTable.compactedFilename(path)));
+ }
+ catch (IOException e)
+ {
+ throw new IOError(e);
+ }
+ tracker.spaceReclaimed(size);
logger.info("Deleted " + path);
- DeletionService.submitDeleteWithRetry(SSTable.indexFilename(path));
-
DeletionService.submitDeleteWithRetry(SSTable.filterFilename(path));
-
DeletionService.submitDeleteWithRetry(SSTable.compactedFilename(path));
}
}
}
Modified:
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableReader.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableReader.java?rev=906631&r1=906630&r2=906631&view=diff
==============================================================================
---
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableReader.java
(original)
+++
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableReader.java
Thu Feb 4 20:04:20 2010
@@ -135,7 +135,7 @@
return sstable;
}
- SSTableDeletingReference phantomReference;
+ private volatile SSTableDeletingReference phantomReference;
// jvm can only map up to 2GB at a time, so we split index/data into
segments of that size when using mmap i/o
private final MappedByteBuffer[] indexBuffers;
private final MappedByteBuffer[] buffers;
@@ -196,11 +196,15 @@
this.indexPositions = indexPositions;
this.spannedIndexDataPositions = spannedIndexDataPositions;
this.bf = bloomFilter;
- phantomReference = new SSTableDeletingReference(this, finalizerQueue);
- finalizers.add(phantomReference);
this.keyCache = keyCache;
}
+ public void addFinalizingReference(SSTableTracker tracker)
+ {
+ phantomReference = new SSTableDeletingReference(tracker, this,
finalizerQueue);
+ finalizers.add(phantomReference);
+ }
+
private static MappedByteBuffer mmap(String filename, long start, int
size) throws IOException
{
RandomAccessFile raf;
Modified:
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableTracker.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableTracker.java?rev=906631&r1=906630&r2=906631&view=diff
==============================================================================
---
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableTracker.java
(original)
+++
incubator/cassandra/trunk/src/java/org/apache/cassandra/io/SSTableTracker.java
Thu Feb 4 20:04:20 2010
@@ -23,11 +23,14 @@
import java.util.*;
import java.io.IOException;
+import java.util.concurrent.atomic.AtomicLong;
public class SSTableTracker implements Iterable<SSTableReader>
{
private volatile Set<SSTableReader> sstables;
+ private final AtomicLong liveSize = new AtomicLong();
+ private final AtomicLong totalSize = new AtomicLong();
public SSTableTracker(Collection<SSTableReader> sstables)
{
@@ -42,12 +45,17 @@
{
assert sstable.getIndexPositions() != null;
sstablesNew.add(sstable);
+ long size = sstable.bytesOnDisk();
+ liveSize.addAndGet(size);
+ totalSize.addAndGet(size);
+ sstable.addFinalizingReference(this);
}
for (SSTableReader sstable : oldSSTables)
{
sstablesNew.remove(sstable);
sstable.markCompacted();
+ liveSize.addAndGet(-sstable.bytesOnDisk());
}
sstables = Collections.unmodifiableSet(sstablesNew);
@@ -102,4 +110,20 @@
}
return n;
}
+
+ public long getLiveSize()
+ {
+ return liveSize.get();
+ }
+
+ public long getTotalSize()
+ {
+ return totalSize.get();
+ }
+
+ public void spaceReclaimed(long size)
+ {
+ totalSize.addAndGet(-size);
+ }
}
+
Modified:
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java?rev=906631&r1=906630&r2=906631&view=diff
==============================================================================
---
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
(original)
+++
incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageService.java
Thu Feb 4 20:04:20 2010
@@ -1472,10 +1472,31 @@
return isClientMode;
}
- public static void requestGC()
+ public synchronized void requestGC()
{
- logger_.info("requesting GC to free disk space");
- System.gc();
+ if (hasUnreclaimedSpace())
+ {
+ logger_.info("requesting GC to free disk space");
+ System.gc();
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e)
+ {
+ throw new AssertionError(e);
+ }
+ }
+ }
+
+ private boolean hasUnreclaimedSpace()
+ {
+ for (ColumnFamilyStore cfs : ColumnFamilyStore.all())
+ {
+ if (cfs.hasUnreclaimedSpace())
+ return true;
+ }
+ return false;
}
// Never ever do this at home. Used by tests.