mirror of https://github.com/apache/cassandra
If SizeEstimatesRecorder misses a 'onDropTable' notification, the size_estimates table will never be cleared for that table.
Patch by Joel Knighton; Reviewed by Ariel Weisberg for CASSANDRA-14905 Co-authored-by: Joel Knighton <jkni@apache.org> Co-authored-by: Aleksandr Sorokoumov <aleksandr.sorokoumov@gmail.com>
This commit is contained in:
parent
ebfa280fac
commit
ddbcff3363
|
|
@ -1,4 +1,5 @@
|
|||
3.0.18
|
||||
* If SizeEstimatesRecorder misses a 'onDropTable' notification, the size_estimates table will never be cleared for that table. (CASSANDRA-14905)
|
||||
* Counters fail to increment in 2.1/2.2 to 3.X mixed version clusters (CASSANDRA-14958)
|
||||
* Streaming needs to synchronise access to LifecycleTransaction (CASSANDRA-14554)
|
||||
* Fix cassandra-stress write hang with default options (CASSANDRA-14616)
|
||||
|
|
|
|||
|
|
@ -1236,6 +1236,32 @@ public final class SystemKeyspace
|
|||
executeInternal(cql, keyspace, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears size estimates for a keyspace (used to manually clean when we miss a keyspace drop)
|
||||
*/
|
||||
public static void clearSizeEstimates(String keyspace)
|
||||
{
|
||||
String cql = String.format("DELETE FROM %s.%s WHERE keyspace_name = ?", NAME, SIZE_ESTIMATES);
|
||||
executeInternal(cql, keyspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A multimap from keyspace to table for all tables with entries in size estimates
|
||||
*/
|
||||
|
||||
public static synchronized SetMultimap<String, String> getTablesWithSizeEstimates()
|
||||
{
|
||||
SetMultimap<String, String> keyspaceTableMap = HashMultimap.create();
|
||||
String cql = String.format("SELECT keyspace_name, table_name FROM %s.%s", NAME, SIZE_ESTIMATES);
|
||||
UntypedResultSet rs = executeInternal(cql);
|
||||
for (UntypedResultSet.Row row : rs)
|
||||
{
|
||||
keyspaceTableMap.put(row.getString("keyspace_name"), row.getString("table_name"));
|
||||
}
|
||||
|
||||
return keyspaceTableMap;
|
||||
}
|
||||
|
||||
public static synchronized void updateAvailableRanges(String keyspace, Collection<Range<Token>> completedRanges)
|
||||
{
|
||||
String cql = "UPDATE system.%s SET ranges = ranges + ? WHERE keyspace_name = ?";
|
||||
|
|
|
|||
|
|
@ -336,9 +336,17 @@ public class CassandraDaemon
|
|||
|
||||
ScheduledExecutors.optionalTasks.schedule(viewRebuild, StorageService.RING_DELAY, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
||||
SystemKeyspace.finishStartup();
|
||||
|
||||
// Clean up system.size_estimates entries left lying around from missed keyspace drops (CASSANDRA-14905)
|
||||
StorageService.instance.cleanupSizeEstimates();
|
||||
|
||||
// schedule periodic dumps of table size estimates into SystemKeyspace.SIZE_ESTIMATES_CF
|
||||
// set cassandra.size_recorder_interval to 0 to disable
|
||||
int sizeRecorderInterval = Integer.getInteger("cassandra.size_recorder_interval", 5 * 60);
|
||||
if (sizeRecorderInterval > 0)
|
||||
ScheduledExecutors.optionalTasks.scheduleWithFixedDelay(SizeEstimatesRecorder.instance, 30, sizeRecorderInterval, TimeUnit.SECONDS);
|
||||
|
||||
// start server internals
|
||||
StorageService.instance.registerDaemon(this);
|
||||
try
|
||||
|
|
@ -380,12 +388,6 @@ public class CassandraDaemon
|
|||
// due to scheduling errors or race conditions
|
||||
ScheduledExecutors.optionalTasks.scheduleWithFixedDelay(ColumnFamilyStore.getBackgroundCompactionTaskSubmitter(), 5, 1, TimeUnit.MINUTES);
|
||||
|
||||
// schedule periodic dumps of table size estimates into SystemKeyspace.SIZE_ESTIMATES_CF
|
||||
// set cassandra.size_recorder_interval to 0 to disable
|
||||
int sizeRecorderInterval = Integer.getInteger("cassandra.size_recorder_interval", 5 * 60);
|
||||
if (sizeRecorderInterval > 0)
|
||||
ScheduledExecutors.optionalTasks.scheduleWithFixedDelay(SizeEstimatesRecorder.instance, 30, sizeRecorderInterval, TimeUnit.SECONDS);
|
||||
|
||||
// Thrift
|
||||
InetAddress rpcAddr = DatabaseDescriptor.getRpcAddress();
|
||||
int rpcPort = DatabaseDescriptor.getRpcPort();
|
||||
|
|
|
|||
|
|
@ -3038,9 +3038,32 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
|||
|
||||
public void refreshSizeEstimates() throws ExecutionException
|
||||
{
|
||||
cleanupSizeEstimates();
|
||||
FBUtilities.waitOnFuture(ScheduledExecutors.optionalTasks.submit(SizeEstimatesRecorder.instance));
|
||||
}
|
||||
|
||||
public void cleanupSizeEstimates()
|
||||
{
|
||||
SetMultimap<String, String> sizeEstimates = SystemKeyspace.getTablesWithSizeEstimates();
|
||||
|
||||
for (Entry<String, Collection<String>> tablesByKeyspace : sizeEstimates.asMap().entrySet())
|
||||
{
|
||||
String keyspace = tablesByKeyspace.getKey();
|
||||
if (!Schema.instance.getKeyspaces().contains(keyspace))
|
||||
{
|
||||
SystemKeyspace.clearSizeEstimates(keyspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String table : tablesByKeyspace.getValue())
|
||||
{
|
||||
if (!Schema.instance.hasCF(Pair.create(keyspace, table)))
|
||||
SystemKeyspace.clearSizeEstimates(keyspace, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowIndexes Allow index CF names to be passed in
|
||||
* @param autoAddIndexes Automatically add secondary indexes if a CF has them
|
||||
|
|
|
|||
|
|
@ -243,6 +243,11 @@ public interface StorageServiceMBean extends NotificationEmitter
|
|||
*/
|
||||
public void refreshSizeEstimates() throws ExecutionException;
|
||||
|
||||
/**
|
||||
* Removes extraneous entries in system.size_estimates.
|
||||
*/
|
||||
public void cleanupSizeEstimates();
|
||||
|
||||
/**
|
||||
* Forces major compaction of a single keyspace
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue