[
https://issues.apache.org/jira/browse/DERBY-6554?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Rick Hillegas updated DERBY-6554:
---------------------------------
Attachment: derby-6554-02-ag-raiseSelfDeadlockAlways.diff
Attaching derby-6554-02-ag-raiseSelfDeadlockAlways.diff. This is a variation on
derby-6554-02-ae-selfDeadlock_sps_compress.diff. This patch always raises a
SelfDeadlock when one is detected, regardless of whether we're asked to wait.
So this patch has the extra logic in
HeapController.lockRowAtSlotNoWaitExclusive() which catches a SelfDeadlock and
returns a null lock.
Tests passed cleanly except for two errors:
1) testDerby48SelfLockingRecoveryDeadlockDetectionOn() (in
LazyDefaultSchemaCreationTest) now fails because an expected timeout isn't
raised. The following script shows the problem. Without the patch, this script
fails on a LOCK_TIMEOUT. With the patch, the script succeeds.
{noformat}
connect 'jdbc:derby:memory:db;create=true';
call syscs_util.syscs_set_database_property( 'derby.locks.deadlockTrace',
'true' );
call syscs_util.syscs_set_database_property( 'derby.locks.waitTimeout', '1' );
call syscs_util.syscs_set_database_property( 'derby.locks.deadlockTimeout', '2'
);
connect 'jdbc:derby:memory:db;user=foo';
autocommit off;
set isolation serializable;
select count(*) from sys.sysschemas;
create table t1(i int);
{noformat}
2) The store unit tests had a failure in T_LockFactory. Not a lot of
information in the failure report:
{noformat}
********* Diff file derbyall/storeall/storeunit/TLockFactory.diff
*** Start: TLockFactory jdk1.8.0 storeall:storeunit 2014-05-09 08:28:09 ***
2 del
< -- Unit Test T_LockFactory finished
2 add
> Shutting down due to unit test failure.
Test Failed.
*** End: TLockFactory jdk1.8.0 storeall:storeunit 2014-05-09 08:28:10 ***
{noformat}
Mike, at this point I don't exactly remember what breaks if we wait for locks
in SequenceUpdater. That logic was arrived at painfully a couple years back. We
can certainly try putting waits back in. Maybe everything will be fine. Or
maybe we will painfully rediscover why we did it this way. One reason you don't
want to wait is because this logic is called during cache eviction/flushing and
during orderly database shutdown. If there are locks on SYSSEQUENCES, then
cache eviction will stall, ddl will stall, and orderly shutdown will block. If
the lock timeout is infinite, this would be very bad. We could try waiting for
the minimum time, a millisecond. I suspect that will cause pile-ups, but I'm
not sure. It also involves a change to the existing apis which is as big as the
change in patch derby-6554-02-af-askToRaiseSelfDeadlock.diff. That is because
the current store interfaces don't let you pass a lock timeout override down
the call stack when you open a conglomerate or fetch a row.
I'll be away for a week. Someone else is welcome to play around with this while
I'm gone and check in one of the solutions if they feel confident. Here's a
summary of the candidate patches:
1) derby-6554-02-ae-selfDeadlock_sps_compress.diff
- passes the tests
- raises a SelfDeadlock only if requested not to wait
- forces HeapController.lockRowAtSlotNoWaitExclusive() to catch an exception
2) derby-6554-02-af-askToRaiseSelfDeadlock.diff
- passes the tests
- SelfDeadlock is raised only if the caller asks for it
- no change to HeapController.lockRowAtSlotNoWaitExclusive()
3) derby-6554-02-ag-raiseSelfDeadlockAlways.diff
- fails 2 tests (see above)
- always raises SelfDeadlock, regardless of whether waiting was requested
- forces HeapController.lockRowAtSlotNoWaitExclusive() to catch an exception
All of these patches fix DERBY-6554. But I don't think that any of these
patches fits your preferences. The first two at least pass the tests.
Thanks for helping me think through these issues.
> Too much contention followed by assert failure when accessing sequence in
> transaction that created it
> -----------------------------------------------------------------------------------------------------
>
> Key: DERBY-6554
> URL: https://issues.apache.org/jira/browse/DERBY-6554
> Project: Derby
> Issue Type: Bug
> Components: SQL
> Affects Versions: 10.9.1.0, 10.11.0.0, 10.10.2.0
> Reporter: Knut Anders Hatlen
> Attachments: D6554.java, D6554_2.java,
> derby-6554-01-aa-useCreationTransaction.diff,
> derby-6554-01-ab-useCreationTransaction.diff,
> derby-6554-01-ac-useCreationTransaction.diff, derby-6554-01-ad-bugfixes.diff,
> derby-6554-02-aa-selfDeadlock.diff, derby-6554-02-ab-selfDeadlock.diff,
> derby-6554-02-ac-selfDeadlock.diff,
> derby-6554-02-ae-selfDeadlock_sps_compress.diff,
> derby-6554-02-af-askToRaiseSelfDeadlock.diff,
> derby-6554-02-ag-raiseSelfDeadlockAlways.diff
>
>
> {noformat}
> ij version 10.11
> ij> connect 'jdbc:derby:memory:db;create=true' as c1;
> ij> autocommit off;
> ij> create sequence seq;
> 0 rows inserted/updated/deleted
> ij> values next value for seq;
> 1
> -----------
> ERROR X0Y84: Too much contention on sequence SEQ. This is probably caused by
> an uncommitted scan of the SYS.SYSSEQUENCES catalog. Do not query this
> catalog directly. Instead, use the SYSCS_UTIL.SYSCS_PEEK_AT_SEQUENCE function
> to view the current value of a query generator.
> ij> rollback;
> ERROR 08003: No current connection.
> ij> connect 'jdbc:derby:memory:db' as c2;
> ij(C2)> autocommit off;
> ij(C2)> create sequence seq;
> 0 rows inserted/updated/deleted
> ij(C2)> values next value for seq;
> 1
> -----------
> ERROR 38000: The exception
> 'org.apache.derby.shared.common.sanity.AssertFailure: ASSERT FAILED Identity
> being changed on a live cacheable. Old uuidString =
> 0ddd00a9-0145-98ba-79df-000007d88b08' was thrown while evaluating an
> expression.
> ERROR XJ001: Java exception: 'ASSERT FAILED Identity being changed on a live
> cacheable. Old uuidString = 0ddd00a9-0145-98ba-79df-000007d88b08:
> org.apache.derby.shared.common.sanity.AssertFailure'.
> {noformat}
--
This message was sent by Atlassian JIRA
(v6.2#6252)