|
[
Permlink
| « Hide
]
Mike Matrigali added a comment - 06/May/07 09:51 PM
From reading the comments it looks like the db boots fine, but there is a persistent problem with some set of the metadata calls.
The described workaround does not always solve the problem.
The bug is apparently inrouduced after we have had a 20 seconds hang (a lock timeout?) like the ones described in
Might be related to DERBY-1996
The attached java file (d2584.java) contains a simple repro for this error. What it does is:
1) create a new database 2) open a connection in repeatable read, auto-commit off 3) select * from sys.sysstatements 4) call DatabaseMetaData.getIndexInfo() -> this will hang for derby.locks.waitTimeout seconds and return successfully 5) call DatabaseMetaData.getIndexInfo() again -> this will throw ArrayIndexOutOfBoundsException I have verified that this fails consistently on 10.2.1.6, 10.2.2.0 and trunk. It does however not fail on 10.0.2.1 and 10.1.3.1. I don't know exactly what's happening, but it seems like an attempt to store the SPS for getIndexInfo() in a nested transaction fails because the parent transaction holds a shared lock on SYSSTATEMENTS. Therefore, an attempt is made to store the SPS in the parent transaction, and that succeeds. However, the SPS that is stored is not complete, so the next call to getIndexInfo() fails.
SPSDescriptor.updateSYSSTATEMENTS() and DataDictionaryImpl.updateSPS() have some logic to ensure that parts of the stored statement are only updated the first time the statement is prepared. But since the first failed attempt in the nested transaction is counted as the first compile, the update in the main transaction does not update everything correctly. The attached patch restores some of the state (one boolean field--initiallyCompilable) when the first update times out, so that the update in the main transaction is regarded as the first compilation. This makes the repro run without errors. Does this sound like a reasonable approach? I have not run any tests yet. Derbyall and suites.All ran cleanly with initiallyCompilable.diff. I'll see if I can add some comments and a test case to it.
Uploaded a new patch which adds a comment about the fix and a JUnit test case that fails without the fix. The patch is ready for review.
Patch looks good. Thanks! Tested on trunk, and the patched solved the corruption problem (although the deadlock (
Patch looks good. I have run the JPOX schema creation tool and the patch fixes the failure.
There are 3 Possible workarounds for this bug:
1) Make JPOX SchemaTool run with READ_COMMITTED (the bug wil only happen for REPEATABLE_READ (or higher?). 2) Make JPOX SchemaTool run in autocommit moed (if that's feasible). 3) Create the database before you run SchemaTool with code like this: Connection c = DriverManager.getConnection(url); DatabaseMetaData dmd = c.getMetaData(); dmd.getIndexInfo("","","",false,false); dmd.getExportedKeys("","",""); dmd.getImportedKeys("","",""); c.close(); This is for SchemaTool in JPOX 1.1.0. If additional metadata calls is needed, you will easily see that in the stackTrace you get from the bug. Thanks Bernt and Øystein for reviewing and testing the patch.
Committed to trunk with revision 536516. Committed to 10.2 with revision 536517. Another possible workaround, avaialble for JPOX 1.1.1 and later: Write an extension to DerbyAdapter implementing
public int getTransactionIsolationForSchemaCreation() { return Connection.TRANSACTION_READ_COMMITTED; } Read http://www.jpox.org/docs/1_1/extensions/datastore_adapter.html on how to plug in the new adapter. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||