db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mi...@apache.org
Subject svn commit: r1505054 - /db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
Date Fri, 19 Jul 2013 22:25:44 GMT
Author: mikem
Date: Fri Jul 19 22:25:44 2013
New Revision: 1505054

URL: http://svn.apache.org/r1505054
Log:
DERBY-6283 indexStat daemon processing tables over and over even when there are
no changes in the tables in soft upgraded database.

backported change #1502319 from trunk to 10.8, some manual merging was
required.

Changed system to always drop orphaned stats during update statistics call.

Without this change soft upgraded systems running on 10.8 or higher derby
software, that had an orphaned statistic would spin forever in the index
stat daemon due to the same problem fixed by DERBY-5680 for hard
upgraded databases.


Modified:
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java?rev=1505054&r1=1505053&r2=1505054&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
Fri Jul 19 22:25:44 2013
@@ -412,16 +412,26 @@ public class IndexStatisticsDaemonImpl
                                         ConglomerateDescriptor[] cds,
                                         boolean asBackgroundTask)
             throws StandardException {
+
+        // can only properly identify disposable stats if cds == null, 
+        // which means we are processing all indexes on the conglomerate.
+        // If user sets 
+        // Property.STORAGE_AUTO_INDEX_STATS_DEBUG_KEEP_DISPOSABLE_STATS
+        // then we will not drop any orphaned stats.
+        // If not, then we will always drop orphaned stats, even in
+        // soft upgraded databases.
         final boolean identifyDisposableStats =
-                (cds == null && !FORCE_OLD_BEHAVIOR && !dbIsPre10_8);
+                (cds == null && !FORCE_OLD_BEHAVIOR);
+
         // Fetch descriptors if we're updating statistics for all indexes.
         if (cds == null) {
             cds = td.getConglomerateDescriptors();
         }
+
         // Extract/derive information from the table descriptor
-        long[] conglomerateNumber = new long[cds.length];
-        ExecIndexRow[] indexRow = new ExecIndexRow[cds.length];
-        UUID[] objectUUID = new UUID[cds.length];
+        long[]          conglomerateNumber      = new long[cds.length];
+        ExecIndexRow[]  indexRow                = new ExecIndexRow[cds.length];
+
 
         TransactionController tc = lcc.getTransactionExecute();
         ConglomerateController heapCC =
@@ -432,6 +442,13 @@ public class IndexStatisticsDaemonImpl
                         ? TransactionController.ISOLATION_READ_UNCOMMITTED
                         : TransactionController.ISOLATION_REPEATABLE_READ
                 );
+
+
+        // create a list of indexes that should have statistics, by looking
+        // at all indexes on the conglomerate. This set is the "non disposable
+        // stat list".
+        UUID[] non_disposable_objectUUID    = new UUID[cds.length];
+
         try
         {
             for (int i = 0; i < cds.length; i++)
@@ -442,9 +459,10 @@ public class IndexStatisticsDaemonImpl
                     continue;
                 }
 
-                conglomerateNumber[i] = cds[i].getConglomerateNumber();
-
-                objectUUID[i] = cds[i].getUUID();
+                // at this point have found a stat for an existing index, 
+                // add it to the list of "non disposable stats"
+                conglomerateNumber[i]        = cds[i].getConglomerateNumber();
+                non_disposable_objectUUID[i] = cds[i].getUUID();
 
                 indexRow[i] =
                     cds[i].getIndexDescriptor().getNullIndexRow(
@@ -457,23 +475,34 @@ public class IndexStatisticsDaemonImpl
             heapCC.close();
         }
 
-        // Check for disposable statistics if we have the required information.
+        // Check for and drop disposable statistics if we have the required 
+        // information.
+        //
         // Note that the algorithm would drop valid statistics entries if
         // working on a subset of the table conglomerates/indexes.
+        // The above loop has populated "cds" with only existing indexes.
+
         if (identifyDisposableStats) {
+
             List existingStats = td.getStatistics();
+            
             StatisticsDescriptor[] stats = (StatisticsDescriptor[])
                     existingStats.toArray(
                         new StatisticsDescriptor[existingStats.size()]);
+
             // For now we know that disposable stats only exist in two cases,
             // and that we'll only get one match for both of them per table:
             //  a) orphaned statistics entries (i.e. DERBY-5681)
             //  b) single-column primary keys (TODO: after DERBY-3790 is done)
+            //
+            //  This loop looks for statistic entries to delete.  It deletes
+            //  those entries that don't have a matching conglomerate in the
+            //  non disposable object list.
             for (int si=0; si < stats.length; si++) {
                 UUID referencedIndex = stats[si].getReferenceID();
                 boolean isValid = false;
                 for (int ci=0; ci < conglomerateNumber.length; ci++) {
-                    if (referencedIndex.equals(objectUUID[ci])) {
+                    if (referencedIndex.equals(non_disposable_objectUUID[ci])) {
                         isValid = true;
                         break;
                     }
@@ -506,7 +535,7 @@ public class IndexStatisticsDaemonImpl
 
         // [x][0] = conglomerate number, [x][1] = start time, [x][2] = stop time
         long[][] scanTimes = new long[conglomerateNumber.length][3];
-        int sci = 0;
+        int      sci       = 0;
         for (int indexNumber = 0;
              indexNumber < conglomerateNumber.length;
              indexNumber++)
@@ -523,10 +552,11 @@ public class IndexStatisticsDaemonImpl
 
             scanTimes[sci][0] = conglomerateNumber[indexNumber];
             scanTimes[sci][1] = System.currentTimeMillis();
+
             // Subtract one for the RowLocation added for indexes.
-            int numCols = indexRow[indexNumber].nColumns() - 1;
-            long[] cardinality = new long[numCols];
-            KeyComparator cmp = new KeyComparator(indexRow[indexNumber]);
+            int           numCols     = indexRow[indexNumber].nColumns() - 1;
+            long[]        cardinality = new long[numCols];
+            KeyComparator cmp         = new KeyComparator(indexRow[indexNumber]);
 
             /* Read uncommitted, with record locking. Actually CS store may
                not hold record locks */
@@ -593,7 +623,8 @@ public class IndexStatisticsDaemonImpl
             int retries = 0;
             while (true) {
                 try {
-                    writeUpdatedStats(lcc, td, objectUUID[indexNumber],
+                    writeUpdatedStats(lcc, td, 
+                            non_disposable_objectUUID[indexNumber],
                             cmp.getRowCount(), cardinality, asBackgroundTask);
                     break;
                 } catch (StandardException se) {



Mime
View raw message