db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dag H. Wanvik (JIRA)" <j...@apache.org>
Subject [jira] Updated: (DERBY-3678) StackOverflowException in deadlock trace
Date Wed, 04 Jun 2008 00:28:45 GMT

     [ https://issues.apache.org/jira/browse/DERBY-3678?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Dag H. Wanvik updated DERBY-3678:
---------------------------------

    Attachment: derby-3678-1.stat
                derby-3678-1.diff

This patch, derby-3678-1, adds a testcase, testDerby3678, to
LazyDefaultSchemaCreationTest. This reproduces the infinite recursion
seen by this issue, if applied without the rest of the patch, which
also contains a fix.

Description of the problem:

A time-out occurs when a second transaction tries to connect if
another connection creates a schema and populates it with a table
without committing. See also DERBY-48.

In the repro test case, after the timeout occurs on the second
connect, the code in Timeout.java tries to construct the diagnostic
lock table when tracing is enabled
(derby.locks.deadlockTrace=true). The first thing Timeout does when
contructing an exception (inside buildLockTableString), is to create a
new instance of TableNameInfo, which it uses to map conglomerate ids
to names to make the print-out more user friendly.

The constructor of TableNameInfo calls
DataDictionary#hashAllTableDescriptorsByTableId, which scans
SYS.SYSTABLES in read uncommitted mode. When an entry is found, a
descriptor for that table is built
(SYSTABLESRowFactory#buildDescriptor).

As part of building the descriptor for the table, buildDescriptor
tries to look up thats table's schema using the UUID of the schema
(found in the row from SYSTABLES describing the table) using
dd.getSchemaDescriptor. This method tries to read SYS.SYSSCHEMAS with
repeatable read mode, which leads to the recursive lock and finally
stack overflow for the thread.

If the lookup of the table's schema is done with read uncommitted
instead, the recursion will not happen. This seems permissible, since
SYS.SYSTABLES is also read in read uncommitted mode from
hashAllTableDescriptorsByTableId, which is only ever called from
TableNameInfo, which, in turn, is only used for diagnostics, as far as
I can tell.

Patch description:

- Adds a new testcase to LazyDefaultSchemaCreationTest
- Makes hashAllTableDescriptorsByTableId use read uncommitted mode when
  accessing SYS.SYSSCHEMAS. Unfortunately I had so add many overloads
  to be able to propagate the isolation mode all the way down. Is
  there a better way?

Running regressions now.


> StackOverflowException in deadlock trace
> ----------------------------------------
>
>                 Key: DERBY-3678
>                 URL: https://issues.apache.org/jira/browse/DERBY-3678
>             Project: Derby
>          Issue Type: Bug
>    Affects Versions: 10.3.2.1
>         Environment: (this is actually in version 10.3.2.2)
> MacOS 10, JDK 1.6
>            Reporter: geoff hendrey
>            Assignee: Dag H. Wanvik
>         Attachments: derby-3678-1.diff, derby-3678-1.stat
>
>
> I am getting a deadlock in SYSTABLE. When I turn on Dderby.locks.deadlockTrace=true,
I get a StackOverflowException
> Derby version The Apache Software Foundation - Apache Derby - 10.3.2.2
> - (618335): instance 80220011-0119-f93f-b912-00000000bced
> on database directory /db/domains/geoff  
> Database Class Loader started - derby.database.classpath=''
> 2008-05-17 23:44:36.380
> GMT Thread[btpool0-2,5,main] (XID = 7556), (SESSIONID = 4), (DATABASE =
> domains/geoff), (DRDAID = null), Cleanup action starting
> java.lang.StackOverflowError
>         at org.apache.derby.impl.sql.execute.GenericExecutionFactory.getValueRow(Unknown
Source)
>         at org.apache.derby.impl.sql.catalog.SYSCONGLOMERATESRowFactory.makeRow(Unknown
Source)
>         at org.apache.derby.impl.sql.catalog.SYSCONGLOMERATESRowFactory.makeEmptyRow(Unknown
> Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.hashAllConglomerateDescriptorsByNumber(Unknown
> Source)
>         at org.apache.derby.impl.services.locks.TableNameInfo.<init>(Unknown Source)
>         at org.apache.derby.impl.services.locks.Timeout.buildLockTableString(Unknown
Source)
>         at org.apache.derby.impl.services.locks.Timeout.createException(Unknown Source)
>         at org.apache.derby.impl.services.locks.Timeout.buildException(Unknown Source)
>         at org.apache.derby.impl.services.locks.ConcurrentLockSet.lockObject(Unknown
Source)
>         at org.apache.derby.impl.services.locks.AbstractPool.lockObject(Unknown Source)
>         at org.apache.derby.impl.services.locks.ConcurrentPool.lockObject(Unknown Source)
>         at org.apache.derby.impl.store.raw.xact.RowLocking3.lockRecordForRead(Unknown
Source)
>         at org.apache.derby.impl.store.access.heap.HeapController.lockRow(Unknown Source)
>         at org.apache.derby.impl.store.access.heap.HeapController.lockRow(Unknown Source)
>         at org.apache.derby.impl.store.access.btree.index.B2IRowLocking3.lockRowOnPage(Unknown
> Source)
>         at org.apache.derby.impl.store.access.btree.index.B2IRowLocking3._lockScanRow(Unknown
> Source)
>         at org.apache.derby.impl.store.access.btree.index.B2IRowLockingRR.lockScanRow(Unknown
> Source)
>         at org.apache.derby.impl.store.access.btree.BTreeForwardScan.fetchRows(Unknown
Source)
>         at org.apache.derby.impl.store.access.btree.BTreeScan.next(Unknown Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.getDescriptorViaIndex(Unknown
> Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.locateSchemaRow(Unknown
Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.getSchemaDescriptor(Unknown
> Source)
>         at org.apache.derby.impl.sql.catalog.SYSTABLESRowFactory.buildDescriptor(Unknown
Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.hashAllTableDescriptorsByTableId(Unknown
> Source)
>         at org.apache.derby.impl.services.locks.TableNameInfo.<init>(Unknown Source)
>         at org.apache.derby.impl.services.locks.Timeout.buildLockTableString(Unknown
Source)
>         at org.apache.derby.impl.services.locks.Timeout.createException(Unknown Source)
>         at org.apache.derby.impl.services.locks.Timeout.buildException(Unknown Source)
>         at org.apache.derby.impl.services.locks.ConcurrentLockSet.lockObject(Unknown
Source)
>         at org.apache.derby.impl.services.locks.AbstractPool.lockObject(Unknown Source)
>         at org.apache.derby.impl.services.locks.ConcurrentPool.lockObject(Unknown Source)
>         at org.apache.derby.impl.store.raw.xact.RowLocking3.lockRecordForRead(Unknown
Source)
>         at org.apache.derby.impl.store.access.heap.HeapController.lockRow(Unknown Source)
>         at org.apache.derby.impl.store.access.heap.HeapController.lockRow(Unknown Source)
>         at org.apache.derby.impl.store.access.btree.index.B2IRowLocking3.lockRowOnPage(Unknown
> Source)
>         at org.apache.derby.impl.store.access.btree.index.B2IRowLocking3._lockScanRow(Unknown
> Source)
>         at org.apache.derby.impl.store.access.btree.index.B2IRowLockingRR.lockScanRow(Unknown
> Source)
>         at org.apache.derby.impl.store.access.btree.BTreeForwardScan.fetchRows(Unknown
Source)
>         at org.apache.derby.impl.store.access.btree.BTreeScan.next(Unknown Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.getDescriptorViaIndex(Unknown
> Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.locateSchemaRow(Unknown
Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.getSchemaDescriptor(Unknown
> Source)
>         at org.apache.derby.impl.sql.catalog.SYSTABLESRowFactory.buildDescriptor(Unknown
Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.hashAllTableDescriptorsByTableId(Unknown
> Source)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message