You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by kr...@apache.org on 2011/03/03 22:28:02 UTC
svn commit: r1076802 -
/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
Author: kristwaa
Date: Thu Mar 3 21:28:02 2011
New Revision: 1076802
URL: http://svn.apache.org/viewvc?rev=1076802&view=rev
Log:
DERBY-5088: ShutdownException raised in istat thread during factory call
Refactored outer-level error handling, and moved context service factory call
inside try/catch.
Patch file: derby-5088-1a-shutdownexception_refactor.diff
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java?rev=1076802&r1=1076801&r2=1076802&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java Thu Mar 3 21:28:02 2011
@@ -307,6 +307,8 @@ public class IndexStatisticsDaemonImpl
/**
* Generates index statistics for all indexes associated with the given
* table descriptor.
+ * <p>
+ * This method is run as a background task.
*
* @param lcc connection context to use to perform the work
* @param td target base table descriptor
@@ -320,7 +322,7 @@ public class IndexStatisticsDaemonImpl
while (true) {
try {
ConglomerateDescriptor[] cds = td.getConglomerateDescriptors();
- tryToGatherStats(lcc, td, cds, AS_BACKGROUND_TASK);
+ updateIndexStatsMinion(lcc, td, cds, AS_BACKGROUND_TASK);
break;
} catch (StandardException se) {
// At this level, we retry the whole operation. If this happens,
@@ -349,51 +351,17 @@ public class IndexStatisticsDaemonImpl
trace(0, "generateStatistics::end");
}
- /**
- * Try to gather statistics. Fail gracefully if we are being shutdown, e.g., the database is killed
- * while we're busy. See DERBY-5037.
- *
- * @param lcc language connection context used to perform the work
- * @param td the table to update index stats for
- * @param cds the conglomerates to update statistics for (non-index
- * conglomerates will be ignored)
- * @param asBackgroundTask whether the updates are done automatically as
- * part of a background task or if explicitly invoked by the user
- * @throws StandardException if something goes wrong
- */
- private void tryToGatherStats(LanguageConnectionContext lcc,
- TableDescriptor td,
- ConglomerateDescriptor[] cds,
- boolean asBackgroundTask)
- throws StandardException
- {
- //
- // Swallow exceptions raised while we are being shutdown.
- //
- try {
- updateIndexStatsMinion( lcc, td, cds, asBackgroundTask );
- }
- catch (StandardException se)
- {
- if ( !isShuttingDown( lcc ) ) { throw se; }
- }
- // to filter assertions raised by debug jars
- catch (RuntimeException re)
- {
- if ( !isShuttingDown( lcc ) ) { throw re; }
- }
- }
/** Return true if we are being shutdown */
- private boolean isShuttingDown( LanguageConnectionContext lcc )
- {
+ private boolean isShuttingDown() {
synchronized (queue) {
- if (daemonDisabled ){
+ if (daemonDisabled || daemonLCC == null){
return true;
+ } else {
+ return !daemonLCC.getDatabase().isActive();
}
}
- return !lcc.getDatabase().isActive();
}
-
+
/**
* Updates the index statistics for the given table and the specified
* indexes.
@@ -699,8 +667,41 @@ public class IndexStatisticsDaemonImpl
*/
public void run() {
final long runStart = System.currentTimeMillis();
- final ContextService ctxService = ContextService.getFactory();
- ctxService.setCurrentContextManager(ctxMgr);
+ ContextService ctxService = null;
+ // Implement the outer-level exception handling here.
+ try {
+ // DERBY-5088: Factory-call may fail.
+ ctxService = ContextService.getFactory();
+ ctxService.setCurrentContextManager(ctxMgr);
+ processingLoop();
+ } catch (ShutdownException se) {
+ // The database is/has been shut down.
+ // Log processing statistics and exit.
+ stop();
+ ctxMgr.cleanupOnError(se, db.isActive());
+ } catch (RuntimeException re) {
+ // DERBY-4037
+ // Extended filtering of runtime exceptions during shutdown:
+ // o assertions raised by debug jars
+ // o runtime exceptions, like NPEs, raised by production jars -
+ // happens because the background thread interacts with store
+ // on a lower level
+ if (!isShuttingDown()) {
+ throw re;
+ }
+ } finally {
+ if (ctxService != null) {
+ ctxService.resetCurrentContextManager(ctxMgr);
+ }
+ runTime += (System.currentTimeMillis() - runStart);
+ }
+ }
+
+ /**
+ * Main processing loop which will compute statistics until the queue
+ * of scheduled work units has been drained.
+ */
+ private void processingLoop() {
// If we don't have a connection to the database, create one.
if (daemonLCC == null) {
try {
@@ -715,8 +716,7 @@ public class IndexStatisticsDaemonImpl
daemonLCC.getTransactionExecute().setNoLockWait(true);
} catch (StandardException se) {
log(AS_BACKGROUND_TASK, null, se,
- "failed to setup index statistics updater");
- ctxService.resetCurrentContextManager(ctxMgr);
+ "failed to initialize index statistics updater");
return;
}
}
@@ -798,9 +798,6 @@ public class IndexStatisticsDaemonImpl
} catch (StandardException se) {
log(AS_BACKGROUND_TASK, null, se, "thread died");
// Do nothing, just let the thread die.
- } catch (ShutdownException se) {
- stop(); // Call stop to log activity statistics.
- ctxMgr.cleanupOnError(se, db.isActive());
} finally {
synchronized (queue) {
runningThread = null;
@@ -818,8 +815,6 @@ public class IndexStatisticsDaemonImpl
log(AS_BACKGROUND_TASK, null, se, "forced rollback failed");
}
}
- ctxService.resetCurrentContextManager(ctxMgr);
- runTime += (System.currentTimeMillis() - runStart);
}
}
@@ -865,7 +860,7 @@ public class IndexStatisticsDaemonImpl
// If there is no running thread and the daemon lcc is still
// around, destroy the transaction and clear the lcc reference.
if (runningThread == null && daemonLCC != null &&
- !isShuttingDown(daemonLCC)) {
+ !isShuttingDown()) {
// try/catch as safe-guard against shutdown race condition.
try {
daemonLCC.getTransactionExecute().destroy();
@@ -894,7 +889,9 @@ public class IndexStatisticsDaemonImpl
// We are not allowed to write into the database, most likely the
// data dictionary. No point to keep doing work we can't gain from.
disable = true;
- } else if (se.getSeverity() >= ExceptionSeverity.DATABASE_SEVERITY) {
+ } else if (isShuttingDown() ||
+ se.getSeverity() >= ExceptionSeverity.DATABASE_SEVERITY) {
+ // DERBY-4037: Swallow exceptions raised during shutdown.
// The database or system is going down. Probably handled elsewhere
// but disable daemon anyway.
disable = true;
@@ -903,7 +900,6 @@ public class IndexStatisticsDaemonImpl
if (disable) {
daemonLCC.getDataDictionary().disableIndexStatsRefresher();
- stop();
}
return disable;
}