db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1624974 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/services/cache/ engine/org/apache/derby/iapi/store/raw/data/ engine/org/apache/derby/impl/services/cache/ engine/org/apache/derby/impl/sql/conn/ engine/org/apache/derby/i...
Date Mon, 15 Sep 2014 09:03:33 GMT
Author: kahatlen
Date: Mon Sep 15 09:03:33 2014
New Revision: 1624974

URL: http://svn.apache.org/r1624974
Log:
DERBY-6733: Implement an MBean for monitoring caches

Add an MBean for the statement cache.

Fix the values returned from getAllocatedEntries() and
getUsedEntries(). The first patch got them mixed up.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/data/DataFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/cache/CacheManager.java
Mon Sep 15 09:03:33 2014
@@ -271,12 +271,26 @@ public interface CacheManager {
 	public Collection values();
 
     /**
+     * <p>
      * Register an MBean that allows user to monitor this cache instance.
      * This is a no-op if the platform does not support Java Management
      * Extensions (JMX).
+     * </p>
+     *
+     * <p>
+     * The MBean will be automatically deregistered when {@link #shutdown()}
+     * is called, or it can be manually deregistered by calling
+     * {@link #deregisterMBean()}.
+     * </p>
      *
      * @param dbName the unique name of the database to which the cache belongs
      * @throws StandardException if an error occurs when registering the MBean
      */
     void registerMBean(String dbName) throws StandardException;
+
+    /**
+     * Deregister the MBean that monitors this cache. If there is no MBean
+     * for this instance, this is a no-op.
+     */
+    void deregisterMBean();
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/data/DataFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/data/DataFactory.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/data/DataFactory.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/data/DataFactory.java
Mon Sep 15 09:03:33 2014
@@ -379,6 +379,24 @@ public interface DataFactory extends Cor
      */
     public StorageFactory getStorageFactory();
 
+    /**
+     * <p>
+     * Get the root directory of the data storage area. It is always
+     * guaranteed to be an absolute path, and it is prefixed with the
+     * JDBC sub-sub-protocol if it is not a directory database. Examples:
+     * </p>
+     *
+     * <dl>
+     *     <dt>{@code /path/to/database}</dt>
+     *     <dd>in case of a directory database</dd>
+     *     <dt>{@code memory:/path/to/database}</dt>
+     *     <dd> in case of a memory database</dd>
+     * </dl>
+     *
+     * @return the root directory of the data storage area
+     */
+    String getRootDirectory();
+
 	public void	stop();
 
     /**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
Mon Sep 15 09:03:33 2014
@@ -135,8 +135,10 @@ final class ClockPolicy implements Repla
     }
 
     @Override
-    public int freeEntries() {
-        return freeEntries.get();
+    public int size() {
+        synchronized (clock) {
+            return clock.size();
+        }
     }
 
     /**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
Mon Sep 15 09:03:33 2014
@@ -625,14 +625,7 @@ final class ConcurrentCache implements C
         if (cleaner != null) {
             cleaner.unsubscribe();
         }
-
-        if (mbean != null) {
-            ManagementService managementService =
-                (ManagementService) Monitor.getSystemModule(Module.JMX);
-            if (managementService != null) {
-                managementService.unregisterMBean(mbean);
-            }
-        }
+        deregisterMBean();
     }
 
     /**
@@ -734,6 +727,18 @@ final class ConcurrentCache implements C
         }
     }
 
+    @Override
+    public void deregisterMBean() {
+        if (mbean != null) {
+            ManagementService managementService =
+                (ManagementService) Monitor.getSystemModule(Module.JMX);
+            if (managementService != null) {
+                managementService.unregisterMBean(mbean);
+            }
+            mbean = null;
+        }
+    }
+
     /** Count a cache hit. */
     private void countHit() {
         if (collectAccessCounts) {
@@ -785,13 +790,13 @@ final class ConcurrentCache implements C
         return maxSize;
     }
 
-    /** Get the number of allocated entries. */
+    /** Get the number of allocated entries in the cache. */
     long getAllocatedEntries() {
-        return cache.size();
+        return replacementPolicy.size();
     }
 
-    /** Get the number of allocated entries that hold valid objects. */
+    /** Get the number of cached objects. */
     long getUsedEntries() {
-        return cache.size() - replacementPolicy.freeEntries();
+        return cache.size();
     }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
Mon Sep 15 09:03:33 2014
@@ -56,12 +56,14 @@ interface ReplacementPolicy {
     void doShrink();
 
     /**
-     * Get the number of free entries that could be reused for new objects
-     * without growing the cache.
+     * Get the number of entries allocated in the data structure that holds
+     * cached objects. This number could include empty entries for objects
+     * that have been removed from the cache, if those entries are still
+     * kept in the data structure for reuse.
      *
-     * @return the number of free entries
+     * @return the number of entries allocated in the cache
      */
-    int freeEntries();
+    int size();
 
     /**
      * The interface for the callback objects that <code>ConcurrentCache</code>

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionFactory.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionFactory.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionFactory.java
Mon Sep 15 09:03:33 2014
@@ -74,6 +74,7 @@ import java.util.Dictionary;
 import java.io.Serializable;
 import org.apache.derby.iapi.util.IdUtil;
 import org.apache.derby.iapi.services.daemon.Serviceable;
+import org.apache.derby.iapi.store.raw.data.DataFactory;
 import org.apache.derby.iapi.util.StringUtil;
 
 /**
@@ -309,25 +310,32 @@ public class GenericLanguageConnectionFa
 												"StatementCache",
 												cacheSize/4,
 												cacheSize);
+
+            // Start a management bean for the statement cache to allow
+            // monitoring through JMX, if it is available and enabled.
+            DataFactory df = (DataFactory)
+                    Monitor.findServiceModule(this, DataFactory.MODULE);
+            singleStatementCache.registerMBean(df.getRootDirectory());
 		}
 
 	}
 
 	/**
 	 * returns the statement cache that this connection should use; currently
-	 * there is a statement cache per connection.
+     * there is a statement cache per database.
 	 */
-	
-
 	public CacheManager getStatementCache()
 	{
 		return singleStatementCache;
 	}
 
 	/**
-	 * Stop this module.  In this case, nothing needs to be done.
+     * Stop this module.
 	 */
 	public void stop() {
+        if (singleStatementCache != null) {
+            singleStatementCache.deregisterMBean();
+        }
 	}
 
 	/*

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseDataFileFactory.java
Mon Sep 15 09:03:33 2014
@@ -1432,10 +1432,7 @@ public class BaseDataFileFactory
 		return rawStoreFactory;
 	}
 
-	/**
-		Get the root directory of the data storage area. Is always guaranteed 
-        to be an absolute path.
-	*/
+    @Override
 	public String getRootDirectory() 
     {
 		return dataDirectory;

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java?rev=1624974&r1=1624973&r2=1624974&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/management/CacheManagerMBeanTest.java
Mon Sep 15 09:03:33 2014
@@ -22,6 +22,7 @@
 package org.apache.derbyTesting.functionTests.tests.management;
 
 import java.sql.PreparedStatement;
+import java.sql.Statement;
 import java.util.Hashtable;
 import java.util.Set;
 import javax.management.ObjectName;
@@ -34,6 +35,10 @@ import org.apache.derbyTesting.junit.Tes
  */
 public class CacheManagerMBeanTest extends MBeanTest {
 
+    private final static int DEFAULT_PAGE_CACHE_SIZE = 1000;
+    private final static int DEFAULT_CONTAINER_CACHE_SIZE = 100;
+    private final static int DEFAULT_STATEMENT_CACHE_SIZE = 100;
+
     public CacheManagerMBeanTest(String name) {
         super(name);
     }
@@ -97,11 +102,11 @@ public class CacheManagerMBeanTest exten
         // Boot the database, so that the MBeans are started.
         getConnection();
 
-        // There should be two CacheManager beans. One for the page cache
-        // and one for the container cache.
+        // There should be three CacheManager beans. One for the page cache,
+        // one for the container cache, and one for the statement cache.
         names = queryMBeans(pattern);
         assertEquals("Incorrect number of MBeans found in " + names,
-                     2, names.size());
+                     3, names.size());
 
         // Shut down the database.
         TestConfiguration.getCurrent().shutdownDatabase();
@@ -130,8 +135,7 @@ public class CacheManagerMBeanTest exten
         assertLongAttribute(0, name, "HitCount");
         assertLongAttribute(0, name, "MissCount");
         assertLongAttribute(0, name, "EvictionCount");
-        // Default page cache size is 1000
-        assertLongAttribute(1000, name, "MaxEntries");
+        assertLongAttribute(DEFAULT_PAGE_CACHE_SIZE, name, "MaxEntries");
         // Cannot reliably tell how many entries to expect.
         // More than 0 for sure.
         Long allocated = (Long) getAttribute(name, "AllocatedEntries");
@@ -180,8 +184,7 @@ public class CacheManagerMBeanTest exten
         assertLongAttribute(0, name, "HitCount");
         assertLongAttribute(0, name, "MissCount");
         assertLongAttribute(0, name, "EvictionCount");
-        // Default container cache size is 100
-        assertLongAttribute(100, name, "MaxEntries");
+        assertLongAttribute(DEFAULT_CONTAINER_CACHE_SIZE, name, "MaxEntries");
         // Cannot reliably tell how many entries to expect.
         // More than 0 for sure.
         Long allocated = (Long) getAttribute(name, "AllocatedEntries");
@@ -189,4 +192,101 @@ public class CacheManagerMBeanTest exten
         Long used = (Long) getAttribute(name, "UsedEntries");
         assertTrue("Used entries: " + used, used > 0);
     }
+
+    /**
+     * Test the {@code CacheManagerMBean} for the statement cache.
+     */
+    public void testStatementCache() throws Exception {
+        getConnection(); // boot the database
+        Set<ObjectName> names =
+                queryMBeans(createObjectName("StatementCache", null));
+
+        assertEquals("Should have a single statement cache", 1, names.size());
+
+        ObjectName name = names.iterator().next();
+
+        assertBooleanAttribute(false, name, "CollectAccessCounts");
+        assertLongAttribute(0, name, "HitCount");
+        assertLongAttribute(0, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+        assertLongAttribute(DEFAULT_STATEMENT_CACHE_SIZE, name, "MaxEntries");
+        // The statement cache is initially empty
+        assertLongAttribute(0, name, "AllocatedEntries");
+        assertLongAttribute(0, name, "UsedEntries");
+
+        // Prepare a statement. Now there should be one allocated entry, and
+        // that entry is also a used entry.
+        prepareStatement("values 1").close();
+        assertLongAttribute(1, name, "AllocatedEntries");
+        assertLongAttribute(1, name, "UsedEntries");
+
+        // One more...
+        prepareStatement("values 2").close();
+        assertLongAttribute(2, name, "AllocatedEntries");
+        assertLongAttribute(2, name, "UsedEntries");
+
+        // Now clear the statement cache. One more entry is allocated (for
+        // the statement that clears the cache), but no entries should be
+        // used after the statement cache is cleared.
+        Statement s = createStatement();
+        s.execute("call syscs_util.syscs_empty_statement_cache()");
+        assertLongAttribute(3, name, "AllocatedEntries");
+        assertLongAttribute(0, name, "UsedEntries");
+
+        // None of the accesses to the statement cache should have been
+        // counted so far.
+        assertLongAttribute(0, name, "HitCount");
+        assertLongAttribute(0, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+
+        // Enable counting of cache accesses.
+        setAttribute(name, "CollectAccessCounts", Boolean.TRUE);
+        assertBooleanAttribute(true, name, "CollectAccessCounts");
+
+        // Prepare a statement. Since the cache is empty, it must be a miss.
+        prepareStatement("values 1").close();
+        assertLongAttribute(0, name, "HitCount");
+        assertLongAttribute(1, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+
+        // One more...
+        prepareStatement("values 2").close();
+        assertLongAttribute(0, name, "HitCount");
+        assertLongAttribute(2, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+
+        // Now, this should cause a hit.
+        prepareStatement("values 1").close();
+        assertLongAttribute(1, name, "HitCount");
+        assertLongAttribute(2, name, "MissCount");
+        assertLongAttribute(0, name, "EvictionCount");
+
+        // Prepare so many statements that the cache is filled twice.
+        for (int i = 0; i < DEFAULT_STATEMENT_CACHE_SIZE * 2; i++) {
+            prepareStatement("values 1, " + i).close();
+        }
+
+        // None of the above statements were already in the cache, so expect
+        // all of them to cause misses.
+        assertLongAttribute(1, name, "HitCount");
+        assertLongAttribute(
+                2 + DEFAULT_STATEMENT_CACHE_SIZE * 2, name, "MissCount");
+
+        // We have prepared 2 + (DEFAULT_STATEMENT_CACHE_SIZE * 2) statements,
+        // and the cache can only hold DEFAULT_STATEMENT_CACHE_SIZE of them,
+        // so expect DEFAULT_STATEMENT_CACHE_SIZE + 2 statements to have been
+        // evicted from the cache.
+        assertLongAttribute(2 + DEFAULT_STATEMENT_CACHE_SIZE,
+                            name, "EvictionCount");
+
+        // Expect the cache to be full.
+        assertLongAttribute(DEFAULT_STATEMENT_CACHE_SIZE, name, "MaxEntries");
+        assertLongAttribute(DEFAULT_STATEMENT_CACHE_SIZE,
+                            name, "AllocatedEntries");
+        assertLongAttribute(DEFAULT_STATEMENT_CACHE_SIZE, name, "UsedEntries");
+
+        // Disable the access counts.
+        setAttribute(name, "CollectAccessCounts", Boolean.FALSE);
+        assertBooleanAttribute(false, name, "CollectAccessCounts");
+    }
 }



Mime
View raw message