You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by "Suresh Thalamati (JIRA)" <ji...@apache.org> on 2007/05/17 13:56:16 UTC

[jira] Updated: (DERBY-700) Derby does not prevent dual boot of database from different classloaders on Linux

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

Suresh Thalamati updated DERBY-700:
-----------------------------------

    Attachment: derby700_singleproperty_v1.stat
                derby700_singleproperty_v1.diff

Attached is a patch with partial implementation of  the intra-jvm db 
lock mechanism to prevent users from running multiple instances of the same
database using different class loaders in the same jvm. Existing 
solution already prevents users from running multiple instances across jvms.

Although I have not assigned this issue to myself, have been working on this
issue on/off for some time. But I don't have free cycles to work on this bug for 
the upcoming release. I am posting the patch with whatever work I have done
sofar. If some one can enhance the attached patch and fix this issue, 
that will be great.

Intra-jvm db lock is provided by using global derby specific jvm instance id.
On a first boot of any derby database in a jvm, an UUID is generated and 
stored in a system property ("derby.storage.jvmInstanceID"). This id is written 
to the dbex.lck file when the database is booted. If the ID in the dbex.lck file 
and the current jvm id stored in the system property
"derby.storage.jvmInstanceID" are same then the database is already booted, and 
an exception will be thrown and database will not be booted. On a database
shutdown , an Invalid JVM id is written to the dbex.lck file, so that if the 
database booted again ID's will not be equal, which means database is not
already booted, the database will be booted successfully. I am using the 
existing UUID factory in the derby to generate the derby jvm id.

Synchronization is done by using the interned strings. Synchronization 
across the JVM is done on "derby.storage.jvmInstanceID" string. And 
Synchronization for a database is done on the database directory. This 
may need to be changed to a database name, because it may not be possible 
to get the canonical path always and it is necessary to synchronize on 
a  string, that is unique to a database in a jvm. 
 

In my earlier proposed solution I mentioned about releasing the db 
locks using finalizer. After doing some testing , I realized there is 
no need to address unlocking the database on garbage collection, 
using the finalizer. My understanding is unless users shutdown 
the database rawStoreDaemon and antiGC thread will hold on to the 
resources and the classes will not be unloaded. So the only way users
can boot an already booted database but not in use using another class 
loader instance in the same jvm is by doing a shutdown from the class 
loader that booted the database. If some thinks this is not 
true,  please correct me. 

To do :

1) cleanup error handling on IOExceptions and add new message for the 
   intra-jvm db lock. 

2) Currently dataDirectory path string is is used for  synchronization to 
   prevent multiple boots of a database. This may need to be changed to 
   the db name.

3) Make the classLoaderBootTest.java run under security manager. 

4)  Add test cases for booting different databases parallelly on different 
    threads with different class loaders. May not be really required , because
    even booting a single database through different threads shoud test 
    the same thing. But it may be better to add a test case, just to be safe!
 

5) Run the test with large number of threads.

6) Anything else I have forgotten !
  
 
Thanks 
-suresh



> Derby does not prevent dual boot of database from different classloaders on Linux
> ---------------------------------------------------------------------------------
>
>                 Key: DERBY-700
>                 URL: https://issues.apache.org/jira/browse/DERBY-700
>             Project: Derby
>          Issue Type: Bug
>          Components: Store
>    Affects Versions: 10.1.2.1
>         Environment: ava -version
> java version "1.4.2_08"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_08-b03)
> Java HotSpot(TM) Client VM (build 1.4.2_08-b03, mixed mode)
>            Reporter: Kathey Marsden
>            Priority: Critical
>         Attachments: DERBY-700.diff, DERBY-700.stat, DERBY-700_v1_use_to_run_DualBootrepro_multithreaded.diff, DERBY-700_v1_use_to_run_DualBootrepro_multithreaded.stat, derby700_singleproperty_v1.diff, derby700_singleproperty_v1.stat, DualBootRepro.java, DualBootRepro2.zip, DualBootRepro_mutltithreaded.tar.bz2
>
>
> Derby does not prevent dual boot from two different classloaders on Linux.
> To reproduce run the  program DualBootRepro with no derby jars in your classpath. The program assumes derby.jar is in 10.1.2.1/derby.jar, you can change the location by changing the DERBY_LIB_DIR variable.
> On Linux the output is:
> $java -cp . DualBootRepro
> Loading derby from file:10.1.2.1/derby.jar
> 10.1.2.1/derby.jar
> Booted database in loader java.net.URLClassLoader@8ed465
> FAIL: Booted database in 2nd loader java.net.URLClassLoader@dc6a77
> On Windows I get the expected output.
> $ java -cp . DualBootRepro
> Loading derby from file:10.1.2.1/derby.jar
> 10.1.2.1/derby.jar
> Booted database in loader java.net.URLClassLoader@1ac04e8
> PASS: Expected exception for dualboot:Another instance of Derby may have already booted the database D:\marsden\repro\dualboot\mydb.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.