Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 364105

Summary: [DB] ImplementationError: "SELECT ..." already in cache
Product: [Modeling] EMF Reporter: Eike Stepper <stepper>
Component: cdo.dbAssignee: Eike Stepper <stepper>
Status: CLOSED FIXED QA Contact: Eike Stepper <stepper>
Severity: normal    
Priority: P3 CC: apeteri, bit2k
Version: 4.2   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
Patch to test_Bugzilla_309467() and test_Bugzilla_309467_ServerRestart to trigger bug 364105
none
Patch for SmartPreparedStatementCache to record allocations of CachedPreparedStatements
none
Proposed fix for SmartPreparedStatementCache none

Description Eike Stepper CLA 2011-11-18 01:25:51 EST
-- Error Log from JUnit --
Class: org.eclipse.emf.cdo.tests.MergingTest
Method: test_Bugzilla_309467_ServerRestart
Actual: null
Expected: null
Stack Trace:
org.eclipse.emf.cdo.tests.config.impl.ConfigTestException: Error in MergingTest.test_Bugzilla_309467_ServerRestart [Combined, H2-branching-ranges, JVM, Native]
	at org.eclipse.emf.cdo.tests.config.impl.ConfigTest.runBare(ConfigTest.java:535)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at org.eclipse.net4j.util.tests.AbstractOMTest.run(AbstractOMTest.java:264)
	at junit.framework.TestSuite.runTest(TestSuite.java:243)
	at org.eclipse.emf.cdo.tests.config.impl.ConfigTestSuite$TestWrapper.runTest(ConfigTestSuite.java:119)
	at junit.framework.TestSuite.run(TestSuite.java:238)
	at junit.framework.TestSuite.runTest(TestSuite.java:243)
	at junit.framework.TestSuite.run(TestSuite.java:238)
	at junit.framework.TestSuite.runTest(TestSuite.java:243)
	at junit.framework.TestSuite.run(TestSuite.java:238)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.eclipse.net4j.signal.RemoteException: org.eclipse.net4j.util.ImplementationError: SELECT cdo_version, cdo_created, cdo_revised, cdo_resource, cdo_container, cdo_feature, folder, name, contents FROM eresource_CDOResource WHERE cdo_id=? AND cdo_branch=? AND (cdo_created<=? AND (cdo_revised=0 OR cdo_revised>=?)) already in cache
	at org.eclipse.net4j.signal.RequestWithConfirmation.getRemoteException(RequestWithConfirmation.java:139)
	at org.eclipse.net4j.signal.RequestWithConfirmation.setRemoteException(RequestWithConfirmation.java:128)
	at org.eclipse.net4j.signal.SignalProtocol.handleRemoteException(SignalProtocol.java:460)
	at org.eclipse.net4j.signal.RemoteExceptionIndication.indicating(RemoteExceptionIndication.java:63)
	at org.eclipse.net4j.signal.Indication.doExtendedInput(Indication.java:55)
	at org.eclipse.net4j.signal.Signal.doInput(Signal.java:326)
	at org.eclipse.net4j.signal.Indication.execute(Indication.java:49)
	at org.eclipse.net4j.signal.Signal.runSync(Signal.java:251)
	at org.eclipse.net4j.signal.Signal.run(Signal.java:147)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: org.eclipse.net4j.util.ImplementationError: SELECT cdo_version, cdo_created, cdo_revised, cdo_resource, cdo_container, cdo_feature, folder, name, contents FROM eresource_CDOResource WHERE cdo_id=? AND cdo_branch=? AND (cdo_created<=? AND (cdo_revised=0 OR cdo_revised>=?)) already in cache
	at org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache$Cache.put(SmartPreparedStatementCache.java:123)
	at org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache.releasePreparedStatement(SmartPreparedStatementCache.java:61)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalBranchingClassMapping.readRevision(HorizontalBranchingClassMapping.java:453)
	at org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.readRevision(DBStoreAccessor.java:221)
	at org.eclipse.emf.cdo.internal.server.Repository.loadRevisions(Repository.java:469)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.loadRevisions(CDORevisionManagerImpl.java:382)
	at org.eclipse.emf.cdo.tests.util.TestRevisionManager.loadRevisions(TestRevisionManager.java:116)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevisions(CDORevisionManagerImpl.java:293)
	at org.eclipse.emf.cdo.tests.util.TestRevisionManager.getRevisions(TestRevisionManager.java:71)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevision(CDORevisionManagerImpl.java:276)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevision(CDORevisionManagerImpl.java:269)
	at org.eclipse.emf.cdo.internal.server.Repository.getRevisionFromBranch(Repository.java:1286)
	at org.eclipse.emf.cdo.internal.server.Repository.loadMergeData(Repository.java:1264)
	at org.eclipse.emf.cdo.internal.server.Repository.getMergeData(Repository.java:1228)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.LoadMergeDataIndication.responding(LoadMergeDataIndication.java:113)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerIndicationWithMonitoring.responding(CDOServerIndicationWithMonitoring.java:170)
	at org.eclipse.net4j.signal.IndicationWithMonitoring.responding(IndicationWithMonitoring.java:90)
	at org.eclipse.net4j.signal.IndicationWithResponse.doExtendedOutput(IndicationWithResponse.java:96)
	at org.eclipse.net4j.signal.Signal.doOutput(Signal.java:296)
	at org.eclipse.net4j.signal.IndicationWithResponse.execute(IndicationWithResponse.java:65)
	at org.eclipse.net4j.signal.IndicationWithMonitoring.execute(IndicationWithMonitoring.java:63)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerReadIndicationWithMonitoring.execute(CDOServerReadIndicationWithMonitoring.java:36)
	... 5 more
Comment 1 Eike Stepper CLA 2012-08-14 22:57:18 EDT
Moving all open issues to 4.2. Open bugs can be ported to 4.1 maintenance after they've been fixed in master.
Comment 2 András Péteri CLA 2012-09-06 16:37:51 EDT
Created attachment 220804 [details]
Patch to test_Bugzilla_309467() and test_Bugzilla_309467_ServerRestart to trigger bug 364105
Comment 3 András Péteri CLA 2012-09-06 16:39:43 EDT
Created attachment 220805 [details]
Patch for SmartPreparedStatementCache to record allocations of CachedPreparedStatements
Comment 4 András Péteri CLA 2012-09-06 16:45:26 EDT
After applying both patches, the following stack trace can be produced by running test_Bugzilla_309467_ServerRestart (but not test_Bugzilla_309467):

org.eclipse.net4j.signal.RemoteException: org.eclipse.net4j.util.ImplementationError: SELECT cdo_version, cdo_created, cdo_revised, cdo_resource, cdo_container, cdo_feature, folder, name, contents FROM eresource_CDOResource WHERE cdo_id=? AND cdo_branch=? AND (cdo_created<=? AND (cdo_revised=0 OR cdo_revised>=?)) already in cache
	at org.eclipse.net4j.signal.RequestWithConfirmation.getRemoteException(RequestWithConfirmation.java:141)
	at org.eclipse.net4j.signal.RequestWithConfirmation.setRemoteException(RequestWithConfirmation.java:130)
	at org.eclipse.net4j.signal.SignalProtocol.handleRemoteException(SignalProtocol.java:467)
	at org.eclipse.net4j.signal.RemoteExceptionIndication.indicating(RemoteExceptionIndication.java:66)
	at org.eclipse.net4j.signal.Indication.doExtendedInput(Indication.java:57)
	at org.eclipse.net4j.signal.Signal.doInput(Signal.java:328)
	at org.eclipse.net4j.signal.Indication.execute(Indication.java:51)
	at org.eclipse.net4j.signal.Signal.runSync(Signal.java:253)
	at org.eclipse.net4j.signal.Signal.run(Signal.java:149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Caused by: org.eclipse.net4j.util.ImplementationError: SELECT cdo_version, cdo_created, cdo_revised, cdo_resource, cdo_container, cdo_feature, folder, name, contents FROM eresource_CDOResource WHERE cdo_id=? AND cdo_branch=? AND (cdo_created<=? AND (cdo_revised=0 OR cdo_revised>=?)) already in cache
	at org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache$Cache.put(SmartPreparedStatementCache.java:126)
	at org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache.releasePreparedStatement(SmartPreparedStatementCache.java:62)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalBranchingClassMapping.readRevision(HorizontalBranchingClassMapping.java:466)
	at org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.readRevision(DBStoreAccessor.java:222)
	at org.eclipse.emf.cdo.internal.server.Repository.loadRevisions(Repository.java:481)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.loadRevisions(CDORevisionManagerImpl.java:381)
	at org.eclipse.emf.cdo.tests.util.TestRevisionManager.loadRevisions(TestRevisionManager.java:116)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevisions(CDORevisionManagerImpl.java:292)
	at org.eclipse.emf.cdo.tests.util.TestRevisionManager.getRevisions(TestRevisionManager.java:71)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevision(CDORevisionManagerImpl.java:275)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevision(CDORevisionManagerImpl.java:268)
	at org.eclipse.emf.cdo.internal.server.Repository.getRevisionFromBranch(Repository.java:1372)
	at org.eclipse.emf.cdo.internal.server.Repository.loadMergeData(Repository.java:1350)
	at org.eclipse.emf.cdo.internal.server.Repository.getMergeData(Repository.java:1314)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.LoadMergeDataIndication.responding(LoadMergeDataIndication.java:113)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerIndicationWithMonitoring.responding(CDOServerIndicationWithMonitoring.java:170)
	at org.eclipse.net4j.signal.IndicationWithMonitoring.responding(IndicationWithMonitoring.java:92)
	at org.eclipse.net4j.signal.IndicationWithResponse.doExtendedOutput(IndicationWithResponse.java:98)
	at org.eclipse.net4j.signal.Signal.doOutput(Signal.java:298)
	at org.eclipse.net4j.signal.IndicationWithResponse.execute(IndicationWithResponse.java:67)
	at org.eclipse.net4j.signal.IndicationWithMonitoring.execute(IndicationWithMonitoring.java:65)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerReadIndicationWithMonitoring.execute(CDOServerReadIndicationWithMonitoring.java:36)
	... 5 more
Caused by: java.lang.Exception: Previous cached statement was initialized here
	at org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache$CachedPreparedStatement.<init>(SmartPreparedStatementCache.java:270)
	at org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache.createCachedPreparedStatement(SmartPreparedStatementCache.java:81)
	at org.eclipse.emf.cdo.server.internal.db.SmartPreparedStatementCache.getPreparedStatement(SmartPreparedStatementCache.java:44)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalBranchingClassMapping.readRevision(HorizontalBranchingClassMapping.java:436)
	at org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.readRevision(DBStoreAccessor.java:222)
	at org.eclipse.emf.cdo.internal.server.Repository.loadRevisions(Repository.java:481)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.loadRevisions(CDORevisionManagerImpl.java:381)
	at org.eclipse.emf.cdo.tests.util.TestRevisionManager.loadRevisions(TestRevisionManager.java:116)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevisions(CDORevisionManagerImpl.java:292)
	at org.eclipse.emf.cdo.tests.util.TestRevisionManager.getRevisions(TestRevisionManager.java:71)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevision(CDORevisionManagerImpl.java:275)
	at org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl.getRevision(CDORevisionManagerImpl.java:268)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.BranchingListTableMappingWithRanges.createBaseChunkReader(BranchingListTableMappingWithRanges.java:1384)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.BranchingListTableMappingWithRanges.readValues(BranchingListTableMappingWithRanges.java:344)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping.readLists(AbstractHorizontalClassMapping.java:359)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalBranchingClassMapping.readRevision(HorizontalBranchingClassMapping.java:455)
	... 24 more

This seems to match Stefan Winkler's description in bug 370105.
Comment 5 András Péteri CLA 2012-10-02 17:10:22 EDT
Created attachment 221814 [details]
Proposed fix for SmartPreparedStatementCache

Stefan's solution for bug 370105 seems to be about carefully avoiding recursion when there's a chance of using a checked out statement twice; I'm agreeing more with bug 337054, comment 16 that CachedPreparedStatements could also be evicted if an attempt is made to check in multiple instances for the same query. The attached fix was created with this in mind.
Comment 6 Eike Stepper CLA 2012-10-30 06:10:15 EDT
Looking at your patch and at SmartPreparedStatementCache I realize that the cache is not quite as smart as it pretends :P

1) Especially with the advent of branching it's not unlikely that recursion is/will be used in other places. too. We should rather optimize for this case than prevent it.

2) evitOne() did never close statements (ouch). And doing so with the current approach of keeping the statements in the CacheList[] array even when they're checked out is dangerous.
Comment 7 Eike Stepper CLA 2012-10-30 08:17:58 EDT
The fundamental issue with recursion over base branches is now fixed via bug 370105.

This bug completely reimplements SmartPreparedStatementCache to make it simpler and close evicted statements.
Comment 8 Eike Stepper CLA 2012-10-30 08:18:38 EDT
commit 6b6d28260f12b40eff4bb93d829d339c0c3fd0cb
Comment 9 Eike Stepper CLA 2012-11-16 04:33:52 EST
*** Bug 393560 has been marked as a duplicate of this bug. ***
Comment 10 Eike Stepper CLA 2013-06-27 03:32:43 EDT
Available in R20130613-1157 (4.2)