You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by gd...@apache.org on 2010/03/18 15:03:55 UTC
svn commit: r924784 - in /cassandra/trunk:
src/java/org/apache/cassandra/config/DatabaseDescriptor.java
src/java/org/apache/cassandra/db/DefsTable.java
src/java/org/apache/cassandra/db/Table.java
test/unit/org/apache/cassandra/db/DefsTest.java
Author: gdusbabek
Date: Thu Mar 18 14:03:55 2010
New Revision: 924784
URL: http://svn.apache.org/viewvc?rev=924784&view=rev
Log:
drop keyspace. patch by Gary Dusbabek, reviewed by Jonathan Ellis. CASSANDRA-861.
Modified:
cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
cassandra/trunk/src/java/org/apache/cassandra/db/DefsTable.java
cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
Modified: cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java?rev=924784&r1=924783&r2=924784&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java Thu Mar 18 14:03:55 2010
@@ -1107,6 +1107,12 @@ public class DatabaseDescriptor
tables.put(ksm.name, ksm);
DatabaseDescriptor.defsVersion = newVersion;
}
+
+ public static void clearTableDefinition(KSMetaData ksm, UUID newVersion)
+ {
+ tables.remove(ksm.name);
+ DatabaseDescriptor.defsVersion = newVersion;
+ }
public static class ConfigurationException extends Exception
{
Modified: cassandra/trunk/src/java/org/apache/cassandra/db/DefsTable.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/DefsTable.java?rev=924784&r1=924783&r2=924784&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/DefsTable.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/DefsTable.java Thu Mar 18 14:03:55 2010
@@ -86,7 +86,7 @@ public class DefsTable
/**
* drop a column family. blockOnDeletion was added to make testing simpler.
*/
- public static Future drop(final CFMetaData cfm, final boolean blockOnDeletion)
+ public static Future drop(final CFMetaData cfm, final boolean blockOnFileDeletion)
{
return executor.submit(new WrappedRunnable()
{
@@ -118,23 +118,7 @@ public class DefsTable
// we don't really need a new segment, but let's force it to be consistent with other operations.
CommitLog.instance().forceNewSegment();
-
- if (blockOnDeletion)
- {
- // notify the compaction manager that it needs to clean up the dropped cf files.
- try
- {
- CompactionManager.instance.submitGraveyardCleanup().get();
- }
- catch (InterruptedException e)
- {
- throw new RuntimeException(e);
- }
- catch (ExecutionException e)
- {
- throw new RuntimeException(e);
- }
- }
+ cleanupDeadFiles(blockOnFileDeletion);
}
});
}
@@ -205,6 +189,45 @@ public class DefsTable
});
}
+ /** drop a keyspace. */
+ public static Future drop(final KSMetaData ksm, final boolean blockOnFileDeletion)
+ {
+ return executor.submit(new WrappedRunnable()
+ {
+ protected void runMayThrow() throws Exception
+ {
+ if (DatabaseDescriptor.getTableDefinition(ksm.name) != ksm)
+ throw new ConfigurationException("Either keyspace doesn't exist or the name of the one you supplied doesn't match with the one being used.");
+
+ // remove the table from the static instances.
+ Table table = Table.clear(ksm.name);
+ if (table == null)
+ throw new ConfigurationException("Table is not active. " + ksm.name);
+
+ // remove all cfs from the table instance.
+ for (CFMetaData cfm : ksm.cfMetaData().values())
+ {
+ CFMetaData.purge(cfm);
+ table.dropCf(cfm.cfName);
+ SystemTable.markForRemoval(cfm);
+ }
+
+ // update internal table.
+ UUID versionId = UUIDGen.makeType1UUIDFromHost(FBUtilities.getLocalAddress());
+ RowMutation rm = new RowMutation(Table.DEFINITIONS, versionId.toString());
+ rm.delete(new QueryPath(SCHEMA_CF, null, ksm.name.getBytes()), System.currentTimeMillis());
+ rm.apply();
+
+ // reset defs.
+ DatabaseDescriptor.clearTableDefinition(ksm, versionId);
+
+ CommitLog.instance().forceNewSegment();
+ cleanupDeadFiles(blockOnFileDeletion);
+
+ }
+ });
+ }
+
/** dumps current keyspace definitions to storage */
public static synchronized void dumpToStorage(UUID version) throws IOException
{
@@ -255,6 +278,26 @@ public class DefsTable
return found;
}
+ private static void cleanupDeadFiles(boolean wait)
+ {
+ Future cleanup = CompactionManager.instance.submitGraveyardCleanup();
+ if (wait)
+ {
+ // notify the compaction manager that it needs to clean up the dropped cf files.
+ try
+ {
+ cleanup.get();
+ }
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (ExecutionException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
// if this errors out, we are in a world of hurt.
private static void renameStorageFiles(String table, String oldCfName, String newCfName) throws IOException
{
Modified: cassandra/trunk/src/java/org/apache/cassandra/db/Table.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java?rev=924784&r1=924783&r2=924784&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/Table.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/Table.java Thu Mar 18 14:03:55 2010
@@ -85,6 +85,7 @@ public class Table
private final Map<String, ColumnFamilyStore> columnFamilyStores = new HashMap<String, ColumnFamilyStore>();
// cache application CFs since Range queries ask for them a _lot_
private SortedSet<String> applicationColumnFamilies;
+ private final TimerTask flushTask;
public static Table open(String table)
{
@@ -106,6 +107,17 @@ public class Table
return tableInstance;
}
+ public static Table clear(String table) throws IOException
+ {
+ synchronized (Table.class)
+ {
+ Table t = instances.remove(table);
+ if (t != null)
+ t.flushTask.cancel();
+ return t;
+ }
+ }
+
public Set<String> getColumnFamilies()
{
return DatabaseDescriptor.getTableDefinition(name).cfMetaData().keySet();
@@ -260,7 +272,7 @@ public class Table
// check 10x as often as the lifetime, so we can exceed lifetime by 10% at most
int checkMs = DatabaseDescriptor.getMemtableLifetimeMS() / 10;
- flushTimer.schedule(new TimerTask()
+ flushTask = new TimerTask()
{
public void run()
{
@@ -269,7 +281,8 @@ public class Table
cfs.forceFlushIfExpired();
}
}
- }, checkMs, checkMs);
+ };
+ flushTimer.schedule(flushTask, checkMs, checkMs);
}
/** removes a cf from internal structures (doesn't change disk files). */
Modified: cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java?rev=924784&r1=924783&r2=924784&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java Thu Mar 18 14:03:55 2010
@@ -113,7 +113,7 @@ public class DefsTest extends CleanupHel
}
@Test
- public void removeCf() throws IOException, ExecutionException, InterruptedException
+ public void dropCf() throws IOException, ExecutionException, InterruptedException
{
// sanity
final KSMetaData ks = DatabaseDescriptor.getTableDefinition("Keyspace1");
@@ -122,7 +122,7 @@ public class DefsTest extends CleanupHel
assert cfm != null;
// write some data, force a flush, then verify that files exist on disk.
- RowMutation rm = new RowMutation(ks.name, "key0");
+ RowMutation rm = new RowMutation(ks.name, "dropCf");
for (int i = 0; i < 100; i++)
rm.add(new QueryPath(cfm.cfName, null, ("col" + i).getBytes()), "anyvalue".getBytes(), 1L);
rm.apply();
@@ -137,7 +137,7 @@ public class DefsTest extends CleanupHel
assert !DatabaseDescriptor.getTableDefinition(ks.name).cfMetaData().containsKey(cfm.cfName);
// any write should fail.
- rm = new RowMutation(ks.name, "key0");
+ rm = new RowMutation(ks.name, "dropCf");
try
{
rm.add(new QueryPath("Standard1", null, "col0".getBytes()), "value0".getBytes(), 1L);
@@ -224,4 +224,53 @@ public class DefsTest extends CleanupHel
IColumn col = cfam.getColumn("col0".getBytes());
assert Arrays.equals("value0".getBytes(), col.value());
}
+
+ @Test
+ public void dropKS() throws IOException, ExecutionException, InterruptedException
+ {
+ // sanity
+ final KSMetaData ks = DatabaseDescriptor.getTableDefinition("Keyspace1");
+ assert ks != null;
+ final CFMetaData cfm = ks.cfMetaData().get("Standard2");
+ assert cfm != null;
+
+ // write some data, force a flush, then verify that files exist on disk.
+ RowMutation rm = new RowMutation(ks.name, "dropKs");
+ for (int i = 0; i < 100; i++)
+ rm.add(new QueryPath(cfm.cfName, null, ("col" + i).getBytes()), "anyvalue".getBytes(), 1L);
+ rm.apply();
+ ColumnFamilyStore store = Table.open(cfm.tableName).getColumnFamilyStore(cfm.cfName);
+ assert store != null;
+ store.forceBlockingFlush();
+ store.getFlushPath();
+ assert DefsTable.getFiles(cfm.tableName, cfm.cfName).size() > 0;
+
+ DefsTable.drop(ks, true).get();
+
+ assert DatabaseDescriptor.getTableDefinition(ks.name) == null;
+
+ // write should fail.
+ rm = new RowMutation(ks.name, "dropKs");
+ try
+ {
+ rm.add(new QueryPath("Standard1", null, "col0".getBytes()), "value0".getBytes(), 1L);
+ rm.apply();
+ assert false : "This mutation should have failed since the CF no longer exists.";
+ }
+ catch (Throwable th)
+ {
+ assert th instanceof IllegalArgumentException;
+ }
+
+ // reads should fail too.
+ try
+ {
+ Table.open(ks.name);
+ }
+ catch (Throwable th)
+ {
+ // this is what has historically happened when you try to open a table that doesn't exist.
+ assert th instanceof NullPointerException;
+ }
+ }
}