Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 10691 invoked from network); 2 Nov 2010 13:46:58 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 2 Nov 2010 13:46:58 -0000 Received: (qmail 80808 invoked by uid 500); 2 Nov 2010 13:47:29 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 80738 invoked by uid 500); 2 Nov 2010 13:47:28 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 80726 invoked by uid 99); 2 Nov 2010 13:47:26 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Nov 2010 13:47:26 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Nov 2010 13:47:24 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 92A8123888BD; Tue, 2 Nov 2010 13:46:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1030043 - /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Date: Tue, 02 Nov 2010 13:46:09 -0000 To: derby-commits@db.apache.org From: kristwaa@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101102134609.92A8123888BD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kristwaa Date: Tue Nov 2 13:46:09 2010 New Revision: 1030043 URL: http://svn.apache.org/viewvc?rev=1030043&view=rev Log: DERBY-4881: Deadlock accessing SYS.SYSSTATISTICS Read table statistics from the system table using READ_UNCOMMITTED to avoid deadlocks with transactions inserting new statistics entries. Modified getDescriptorViaIndexMinon to allow returning multiple tuple descriptors also when isolation level is READ_UNCOMMITTED. Removed one overload of getDescriptorViaIndex (cleanup). Patch file: derby-4881-1b-deadlock_fix.diff Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=1030043&r1=1030042&r2=1030043&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Tue Nov 2 13:46:09 2010 @@ -1655,6 +1655,7 @@ public final class DataDictionaryImpl (TupleDescriptor) null, (List) null, false, + TransactionController.ISOLATION_REPEATABLE_READ, tc); } @@ -4926,9 +4927,16 @@ public final class DataDictionaryImpl false); } - /** get all the statistiscs descriptors for a given table. - * @param td Table Descriptor for which I need statistics - */ + /** + * Returns all the statistics descriptors for the given table. + *

+ * NOTE: As opposed to most other data dictionary lookups, this operation is + * performed with isolation level READ_UNCOMMITTED. The reason is to avoid + * deadlocks with inserts into the statistics system table. + * + * @param td {@code TableDescriptor} for which I need statistics + * @return A list of tuple descriptors, possibly empty. + */ public List getStatisticsDescriptors(TableDescriptor td) throws StandardException { @@ -4940,13 +4948,16 @@ public final class DataDictionaryImpl UUIDStringOrderable = getIDValueAsCHAR(td.getUUID()); ExecIndexRow keyRow = exFactory.getIndexableRow(1); keyRow.setColumn(1, UUIDStringOrderable); - + getDescriptorViaIndex(SYSSTATISTICSRowFactory.SYSSTATISTICS_INDEX1_ID, - keyRow, - (ScanQualifier [][])null, - ti, - (TupleDescriptor)null, - statDescriptorList, false); + keyRow, + (ScanQualifier [][])null, + ti, + (TupleDescriptor)null, + statDescriptorList, + false, + TransactionController.ISOLATION_READ_UNCOMMITTED, + getTransactionCompile()); return statDescriptorList; } @@ -8455,63 +8466,16 @@ public final class DataDictionaryImpl // Get the current transaction controller TransactionController tc = getTransactionCompile(); - return getDescriptorViaIndexMinion( - indexId, - keyRow, - scanQualifiers, - ti, - parentTupleDescriptor, - list, - forUpdate, - TransactionController.ISOLATION_REPEATABLE_READ, - tc); - } - - /** - * Return a (single or list of) catalog row descriptor(s) from a - * system table where the access is from the index to the heap. - * - * This overload variant takes an explicit tc, in contrast to the normal - * one which uses the one returned by getTransactionCompile. - * - * @param indexId The id of the index (0 to # of indexes on table) to use - * @param keyRow The supplied ExecIndexRow for search - * @param ti The TabInfoImpl to use - * @param parentTupleDescriptor The parentDescriptor, if applicable. - * @param list The list to build, if supplied. If null, then - * caller expects a single descriptor - * @param forUpdate Whether or not to open the index for update. - * @param tc Transaction controller - * - * @return The last matching descriptor - * - * @exception StandardException Thrown on error - */ - private final TupleDescriptor getDescriptorViaIndex( - int indexId, - ExecIndexRow keyRow, - ScanQualifier [][] scanQualifiers, - TabInfoImpl ti, - TupleDescriptor parentTupleDescriptor, - List list, - boolean forUpdate, - TransactionController tc) - throws StandardException - { - if (tc == null) { - tc = getTransactionCompile(); - } - - return getDescriptorViaIndexMinion( - indexId, - keyRow, - scanQualifiers, - ti, - parentTupleDescriptor, - list, - forUpdate, - TransactionController.ISOLATION_REPEATABLE_READ, - tc); + return getDescriptorViaIndexMinion( + indexId, + keyRow, + scanQualifiers, + ti, + parentTupleDescriptor, + list, + forUpdate, + TransactionController.ISOLATION_REPEATABLE_READ, + tc); } /** @@ -8585,7 +8549,6 @@ public final class DataDictionaryImpl CatalogRowFactory rf = ti.getCatalogRowFactory(); ConglomerateController heapCC; ExecIndexRow indexRow1; - ExecIndexRow indexTemplateRow; ExecRow outRow; RowLocation baseRowLocation; ScanController scanController; @@ -8597,13 +8560,6 @@ public final class DataDictionaryImpl TransactionController.ISOLATION_REPEATABLE_READ || isolationLevel == TransactionController.ISOLATION_READ_UNCOMMITTED); - - if (isolationLevel == - TransactionController.ISOLATION_READ_UNCOMMITTED) { - // list not used for this case - SanityManager.ASSERT(list == null); - } - } outRow = rf.makeEmptyRow(); @@ -8716,7 +8672,10 @@ public final class DataDictionaryImpl // possibly see that the base row does not exist even if the // index row did. This mode is currently only used by // TableNameInfo's call to hashAllTableDescriptorsByTableId, - // cf. DERBY-3678. A table's schema descriptor is attempted + // cf. DERBY-3678, and by getStatisticsDescriptors, + // cf. DERBY-4881. + // + // For the former call, a table's schema descriptor is attempted // read, and if the base row for the schema has gone between // reading the index and the base table, the table that needs // this information has gone, too. So, the table should not @@ -8752,7 +8711,7 @@ public final class DataDictionaryImpl { break; } - else + else if (td != null) { list.add(td); } @@ -9440,7 +9399,6 @@ public final class DataDictionaryImpl { TabInfoImpl ti = getNonCoreTI(SYSSEQUENCES_CATALOG_NUM); ExecIndexRow keyRow = null; - ExecRow row; keyRow = (ExecIndexRow)exFactory.getIndexableRow(1); keyRow.setColumn(1, new SQLChar( sequenceIDstring ) ); @@ -9448,7 +9406,7 @@ public final class DataDictionaryImpl rowLocation[ 0 ] = ti.getRowLocation( tc, keyRow, SYSSEQUENCESRowFactory.SYSSEQUENCES_INDEX1_ID ); sequenceDescriptor[ 0 ] = (SequenceDescriptor) - getDescriptorViaIndexMinion + getDescriptorViaIndex ( SYSSEQUENCESRowFactory.SYSSEQUENCES_INDEX1_ID, keyRow,