Fix Setting Virtual Table to update after startup config properties gc_log_threshold_in_ms, gc_warn_threshold_in_ms, conf.index_summary_capacity_in_mb, prepared_statements_cache_size_mb, key_cache_size_in_mb, counter_cache_size_in_mb
patch by Ekaterina Dimitrova; reviewed by Andres de la Pena for CASSANDRA-17737
diff --git a/CHANGES.txt b/CHANGES.txt
index 507fe7d..12b68b2 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,7 @@
4.0.6
+ * Fix Setting Virtual Table - update after startup config properties gc_log_threshold_in_ms, gc_warn_threshold_in_ms,
+ conf.index_summary_capacity_in_mb, prepared_statements_cache_size_mb, key_cache_size_in_mb, counter_cache_size_in_mb
+ (CASSANDRA-17737)
* Fix Settings Virtual Table - index_summary_resize_interval and index_summary_capacity were not updated after startup (CASSANDRA-17735)
* Clean up ScheduledExecutors, CommitLog, and MessagingService shutdown for in-JVM dtests (CASSANDRA-17731)
* Remove extra write to system table for prepared statements (CASSANDRA-17764)
diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java
index 049c4cc..c6b8ca7 100644
--- a/src/java/org/apache/cassandra/config/Config.java
+++ b/src/java/org/apache/cassandra/config/Config.java
@@ -356,8 +356,8 @@
public volatile Long index_summary_capacity_in_mb;
public volatile int index_summary_resize_interval_in_minutes = 60;
- public int gc_log_threshold_in_ms = 200;
- public int gc_warn_threshold_in_ms = 1000;
+ public volatile int gc_log_threshold_in_ms = 200;
+ public volatile int gc_warn_threshold_in_ms = 1000;
// TTL for different types of trace events.
public int tracetype_query_ttl = (int) TimeUnit.DAYS.toSeconds(1);
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index f1dc6ef..82a5ec7 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -699,6 +699,9 @@
if (preparedStatementsCacheSizeInMB <= 0)
throw new NumberFormatException(); // to escape duplicating error message
+
+ // we need this assignment for the Settings virtual table - CASSANDRA-17734
+ conf.prepared_statements_cache_size_mb = preparedStatementsCacheSizeInMB;
}
catch (NumberFormatException e)
{
@@ -715,6 +718,9 @@
if (keyCacheSizeInMB < 0)
throw new NumberFormatException(); // to escape duplicating error message
+
+ // we need this assignment for the Settings Virtual Table - CASSANDRA-17734
+ conf.key_cache_size_in_mb = keyCacheSizeInMB;
}
catch (NumberFormatException e)
{
@@ -738,6 +744,9 @@
+ conf.counter_cache_size_in_mb + "', supported values are <integer> >= 0.", false);
}
+ // we need this assignment for the Settings virtual table - CASSANDRA-17735
+ conf.counter_cache_size_in_mb = counterCacheSizeInMB;
+
// if set to empty/"auto" then use 5% of Heap size
indexSummaryCapacityInMB = (conf.index_summary_capacity_in_mb == null)
? Math.max(1, (int) (Runtime.getRuntime().totalMemory() * 0.05 / 1024 / 1024))
@@ -747,6 +756,9 @@
throw new ConfigurationException("index_summary_capacity_in_mb option was set incorrectly to '"
+ conf.index_summary_capacity_in_mb + "', it should be a non-negative integer.", false);
+ // we need this assignment for the Settings virtual table - CASSANDRA-17735
+ conf.index_summary_capacity_in_mb = indexSummaryCapacityInMB;
+
if (conf.user_defined_function_fail_timeout < 0)
throw new ConfigurationException("user_defined_function_fail_timeout must not be negative", false);
if (conf.user_defined_function_warn_timeout < 0)
@@ -3015,6 +3027,11 @@
return conf.gc_log_threshold_in_ms;
}
+ public static void setGCLogThreshold(int gcLogThreshold)
+ {
+ conf.gc_log_threshold_in_ms = gcLogThreshold;
+ }
+
public static EncryptionContext getEncryptionContext()
{
return encryptionContext;
@@ -3025,6 +3042,11 @@
return conf.gc_warn_threshold_in_ms;
}
+ public static void setGCWarnThreshold(int threshold)
+ {
+ conf.gc_warn_threshold_in_ms = threshold;
+ }
+
public static boolean isCDCEnabled()
{
return conf.cdc_enabled;
diff --git a/src/java/org/apache/cassandra/service/GCInspector.java b/src/java/org/apache/cassandra/service/GCInspector.java
index 02fd720..0d42e72 100644
--- a/src/java/org/apache/cassandra/service/GCInspector.java
+++ b/src/java/org/apache/cassandra/service/GCInspector.java
@@ -28,11 +28,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
@@ -54,8 +51,6 @@
{
public static final String MBEAN_NAME = "org.apache.cassandra.service:type=GCInspector";
private static final Logger logger = LoggerFactory.getLogger(GCInspector.class);
- private volatile long gcLogThreshholdInMs = DatabaseDescriptor.getGCLogThreshold();
- private volatile long gcWarnThreasholdInMs = DatabaseDescriptor.getGCWarnThreshold();
/*
* The field from java.nio.Bits that tracks the total number of allocated
@@ -293,9 +288,9 @@
break;
}
- if (gcWarnThreasholdInMs != 0 && duration > gcWarnThreasholdInMs)
+ if (getGcWarnThresholdInMs() != 0 && duration > getGcWarnThresholdInMs())
logger.warn(sb.toString());
- else if (duration > gcLogThreshholdInMs)
+ else if (duration > getGcLogThresholdInMs())
logger.info(sb.toString());
else if (logger.isTraceEnabled())
logger.trace(sb.toString());
@@ -346,37 +341,43 @@
public void setGcWarnThresholdInMs(long threshold)
{
+ long gcLogThresholdInMs = getGcLogThresholdInMs();
if (threshold < 0)
throw new IllegalArgumentException("Threshold must be greater than or equal to 0");
- if (threshold != 0 && threshold <= gcLogThreshholdInMs)
- throw new IllegalArgumentException("Threshold must be greater than gcLogTreasholdInMs which is currently "
- + gcLogThreshholdInMs);
- gcWarnThreasholdInMs = threshold;
+ if (threshold != 0 && threshold <= gcLogThresholdInMs)
+ throw new IllegalArgumentException("Threshold must be greater than gcLogThresholdInMs which is currently "
+ + gcLogThresholdInMs);
+ if (threshold > Integer.MAX_VALUE)
+ throw new IllegalArgumentException("Threshold must be less than Integer.MAX_VALUE");
+ DatabaseDescriptor.setGCWarnThreshold((int)threshold);
}
public long getGcWarnThresholdInMs()
{
- return gcWarnThreasholdInMs;
+ return DatabaseDescriptor.getGCWarnThreshold();
}
public void setGcLogThresholdInMs(long threshold)
{
if (threshold <= 0)
- throw new IllegalArgumentException("Threashold must be greater than 0");
- if (gcWarnThreasholdInMs != 0 && threshold > gcWarnThreasholdInMs)
- throw new IllegalArgumentException("Threashold must be less than gcWarnTreasholdInMs which is currently "
- + gcWarnThreasholdInMs);
- gcLogThreshholdInMs = threshold;
+ throw new IllegalArgumentException("Threshold must be greater than 0");
+
+ long gcWarnThresholdInMs = getGcWarnThresholdInMs();
+ if (gcWarnThresholdInMs != 0 && threshold > gcWarnThresholdInMs)
+ throw new IllegalArgumentException("Threshold must be less than gcWarnThresholdInMs which is currently "
+ + gcWarnThresholdInMs);
+
+ DatabaseDescriptor.setGCLogThreshold((int) threshold);
}
public long getGcLogThresholdInMs()
{
- return gcLogThreshholdInMs;
+ return DatabaseDescriptor.getGCLogThreshold();
}
public long getStatusThresholdInMs()
{
- return gcWarnThreasholdInMs != 0 ? gcWarnThreasholdInMs : gcLogThreshholdInMs;
+ return getGcWarnThresholdInMs() != 0 ? getGcWarnThresholdInMs() : getGcLogThresholdInMs();
}
}
diff --git a/test/unit/org/apache/cassandra/service/GCInspectorTest.java b/test/unit/org/apache/cassandra/service/GCInspectorTest.java
index 7e3a3d3..bcdf023 100644
--- a/test/unit/org/apache/cassandra/service/GCInspectorTest.java
+++ b/test/unit/org/apache/cassandra/service/GCInspectorTest.java
@@ -64,11 +64,16 @@
{
gcInspector.setGcWarnThresholdInMs(0);
Assert.assertEquals(gcInspector.getStatusThresholdInMs(), gcInspector.getGcLogThresholdInMs());
+ Assert.assertEquals(0, DatabaseDescriptor.getGCWarnThreshold());
+ Assert.assertEquals(200, DatabaseDescriptor.getGCLogThreshold());
}
@Test(expected=IllegalArgumentException.class)
public void ensureLogLessThanWarn()
{
+ Assert.assertEquals(200, gcInspector.getGcLogThresholdInMs());
+ gcInspector.setGcWarnThresholdInMs(1000);
+ Assert.assertEquals(1000, gcInspector.getGcWarnThresholdInMs());
gcInspector.setGcLogThresholdInMs(gcInspector.getGcWarnThresholdInMs() + 1);
}
@@ -77,6 +82,16 @@
{
gcInspector.setGcLogThresholdInMs(200);
gcInspector.setGcWarnThresholdInMs(1000);
+ Assert.assertEquals(200, DatabaseDescriptor.getGCLogThreshold());
+ Assert.assertEquals(200, gcInspector.getGcLogThresholdInMs());
+ Assert.assertEquals(1000, DatabaseDescriptor.getGCWarnThreshold());
+ Assert.assertEquals(1000, gcInspector.getGcWarnThresholdInMs());
}
-
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testMaxValue()
+ {
+ gcInspector.setGcLogThresholdInMs(200);
+ gcInspector.setGcWarnThresholdInMs(Integer.MAX_VALUE+1L);
+ }
}