db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Knut Anders Hatlen (JIRA)" <j...@apache.org>
Subject [jira] Updated: (DERBY-3693) Deadlocks accessing DB metadata
Date Thu, 29 May 2008 12:26:45 GMT

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

Knut Anders Hatlen updated DERBY-3693:
--------------------------------------

    Attachment: deadlock.diff

It's just a guess, but perhaps the attached patch deadlock.diff solves the problem. Stored
prepared statements (which are used for the meta-data queries) are compiled in a nested transaction
so that locks on system tables can be released before the main transaction is completed. If
the main transaction already has a lock on something the nested transaction also needs to
lock, the nested transaction may get a lock timeout, in which case we retry the operation
in the parent transaction. We don't retry if the nested transaction runs into a deadlock,
which is what happens in Svata's case. I don't think it's possible that the nested transaction
runs into a deadlock with the main transaction, since the main transaction isn't waiting for
any locks while the nested transaction is executing, but it may perhaps happen if there are
more threads involved?

Anyway, I just wanted to throw out the idea. The patch has not been tested.

> Deadlocks accessing DB metadata
> -------------------------------
>
>                 Key: DERBY-3693
>                 URL: https://issues.apache.org/jira/browse/DERBY-3693
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions: 10.3.2.1, 10.3.3.0, 10.4.1.3
>         Environment: Linux amd64 or Windows 32bit
>            Reporter: Svata Dedic
>         Attachments: deadlock.diff
>
>
> My code changes DB structure (create a column), then immediately after setting autocommit
back to true, the code rescans the DB metadata
> DatabaseMetaData.getColumns(catalog, schemaName, tableName, null);
> I am sometimes getting a deadlock with these operations:
> 2008-04-16 19:50:47.833 GMT Thread[Default RequestProcessor,1,system] (XID = 569844),
(SESSIONID = 2), (DATABASE = /..../a3/.config/localdb/db), (DRDAID = null), Cleanup action
starting 2008-04-16 19:50:47.833 GMT Thread[Default RequestProcessor,1,system] (XID = 569844),
(SESSIONID = 2),  (DATABASE = /..../IJCProjects/a3/.config/localdb/db), (DRDAID = null), Failed
Statement is: EXECUTE STATEMENT SYS."getColumns" ERROR 40XL2: A lock could not be obtained
within the time requested.
> The lockTable dump is:
> 2008-04-16 19:50:47.796 GMT
> XID       |TYPE         |MODE|LOCKCOUNT|LOCKNAME                                    
            |STATE|TABLETYPE /LOCKOBJ                   |INDEXNAME / CONTAINER_ID / MODE for
LATCH only)  |TABLENAME / CONGLOM_ID                |
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> *** The following row is the victim ***
> 569852    |ROW          |X   |0        |(44,7)                                      
         |WAIT |S                      |NULL |SYSSTATEMENTS                         | 
> *** The above row is the victim ***
> The stacktrace of the operation causing the deadlock is 
>         at org.apache.derby.iapi.error.StandardException.newException(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.lockRecordForWrite(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.fetchNext(Unknown Source)

>         at org.apache.derby.impl.sql.catalog.TabInfoImpl.updateRow(Unknown Source) 
>         at org.apache.derby.impl.sql.catalog.TabInfoImpl.updateRow(Unknown Source)
>         at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.updateSPS(Unknown Source
)
>         at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.updateSYSSTATEMENTS(Unknown
Source)
>         at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(Unknown
Source)
>         at org.apache.derby.iapi.sql.dictionary.SPSDescriptor.getPreparedStatement(Unknown
Source)
>         at org.apache.derby.impl.sql.compile.ExecSPSNode.generate(Unknown Source)
>         at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
>         at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
>         at org.apache.derby.impl.sql.GenericPreparedStatement.rePrepare(Unknown Source)
>         at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
>         at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
>         at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown
Source)
>         at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeQuery(Unknown Source)

>         at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.doGetCols(Unknown Source)
>         at org.apache.derby.impl.jdbc.EmbedDatabaseMetaData.getColumns(Unknown Source)
> I've seen the deadlock occur during several get-metadata operations (getImportedKeys,
...), each time waiting on the SYSSTATEMENTS apparently because of internally constructed
PreparedStatement. The lock eventually times out and the locked out operation completes without
error.
> When the deadlock occurs, the "real" SQL into systables is being compiled (I traced this
sql to be the value of "getColumns" key in org/apache/derby/impl/jdbc/metadata.properties
file):
> ---------%<-----------------------%<--------------
> Begin compiling prepared statement: SELECT CAST ('' AS VARCHAR(128)) AS PKTABLE_CAT,
S.SCHEMANAME AS PKTABLE_SCHEM, TABLENAME AS
> PKTABLE_NAME, COLS.COLUMNNAME AS PKCOLUMN_NAME, CAST ('' AS VARCHAR(128)) AS FKTABLE_CAT,
FKTABLE_SCHEM, FKTABLE_NAME, FKCOLUMN_NAME, CAST ...
> ---------%<-----------------------%<--------------

-- 
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