It should be possible to build a 1.5 specific solution, though Bryan has
not succeeded yet in getting the build side of the solution to work.  Of
course such a solution will only make 1.5 and future versions go faster.
In general I think it is better to use the native java support if possible, but of course that is up to you. It may also be the case that
your added class is less work than reorganizing the code to provide a
pre-1.4 version and post-1.5 version.

I know someone had mentioned this issue before and that they had a queue
of open I/O working (rather than a queue of waiters on the single I/O), did I miss you posting a patch for that?

Knut Anders Hatlen (JIRA) wrote:
[ http://issues.apache.org/jira/browse/DERBY-733?page=comments#action_12358925 ]
Knut Anders Hatlen commented on DERBY-733:
------------------------------------------

I have tried to put calls to the lock() and unlock() methods in the
Java 1.5 ReentrantLock class around the synchronized block. With this
change, the difference between the maximum response time and the
average response time is decreased to an acceptable level.

Since Derby can't rely on features from Java 1.5, we have to implement
our own lock class which works on Java 1.3 and 1.4. This should be
relatively simple. I will try to implement a class which can be used
as a drop-in replacement for java.util.concurrent.locks.ReentrantLock
and test it to be sure that it doesn't pose any significant
overhead. I think the overhead posed by maintaining a queue of waiters
will be small compared to the time it takes to read a page from the
disk.


Starvation in RAFContainer.readPage()
-------------------------------------

        Key: DERBY-733
        URL: http://issues.apache.org/jira/browse/DERBY-733
    Project: Derby
       Type: Bug
 Components: Performance, Store
   Versions: 10.2.0.0, 10.1.2.1, 10.1.3.0, 10.1.2.2
Environment: Solaris x86 and Linux with Sun JVM 1.5.0. Derby embedded and 
client/server.
   Reporter: Knut Anders Hatlen
   Assignee: Knut Anders Hatlen


When Derby is completely disk bound, threads might be starved in
RAFContainer.readPage(). This is a real problem when multiple clients
are repeatedly accessing one or a small number of large tables. In
cases like this, I have observed very high maximum response times
(several minutes in the worst cases) on simple transactions. The
average response time is not affected by this.
The starvation is caused by a synchronized block in
RAFContainer.readPage():
 synchronized (this) {
     fileData.seek(pageOffset);
     fileData.readFully(pageData, 0, pageSize);
 }
If many threads want to read pages from the same file, there will be a
long queue of threads waiting for this monitor. Since the Java
specification does not guarantee that threads waiting for monitors are
treated fairly, some threads might have to wait for a long time before
they get the monitor. (Usually, a couple of threads get full throughput
while the others have to wait.)



Reply via email to