[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Some questions about Ozone





Falko Braeutigam wrote:

> Daniel, if possible, please let's keep this discussion in the mail list.

Sorry, I omitted the CC to the list by accident.

>
>
> On Sat, 12 May 2001, you wrote:
> > > The exclusion methods are there to protect the object table and name table from
> > > being read or modified while a transaction is commiting.
> >
> > Sorry, I must be missing something here.  I just looked over the name
> > table code, and it looks to me as if every access to the global name
> > table (WizardStore.nameTable) (as well as every access to the
> > per-transaction nameTable's) is inside a "synchronized" method
> > of the singleton WizardStore object.  It seems like that would take
> > care of any concurrency problems, no?
> True, but...
>
> name table and id table are never changed except in the prepare/commit of a
> transaction. Thus I just have to make sure that nobody reads both tables while
> they are updated. Of course, synchronizing would works but results in poor
> performance because then also read accesses are synchronized. A not that
> restrictive MROW lock also produces correct results and should scale much
> better. The xxxExclusion() methods are my (not that clever) attempt to quickly
> implement such a MROW lock.
>
> So yes, name table is synchronized. This is a correct approach and does not
> affect performance that much because name table accesses are unfrequent in
> comparison to id table. Doing this also for the id table would mean to make
> ozone totally unusable for more than one thread.

I see.  So the real issue is the id table.  Each entry in the id table maps from
an object id to the cluster id of the cluster containing the object.  Maybe
it's posible to take advantage of the fact that the object id numbers are
only ever used once, and all of the transactions are drawing upon the same
source of object id numbers so that no two concurrent transactions will ever allocate
the
same id number. So if one transaction creates a new object and inserts
a new entry into the id table, and nothing stops a second transaction from
"seeing" that entry, there won't actually be any problem, because the
second transaction would never "look for" that entry, since it would
never "see" that object id number.

I think that you can do a similar trick for object
deletion.  Suppose transaction T1 attempts to delete object O123.
So it attempts to write-lock O123, and let's suppose it succeeds
and gets the write-lock.  Next, transaction T2 tries to access object
O123, and it tries to get a read or write lock on O123 and waits
for T1 to commit.  Next, T1 commits. Now, we don't want to hold
a global lock on the ID table during the commit of T1.  So at some
point after T1 commits, T1's thread will remove O123 from the
global object table.  But since we're not holding a global lock, there
is a window of time after T1 commits and before O123 is removed
from the table.  OK, so T2's thread wakes up, and in that window
it is able to "see" the object ID entry for O123, and it gets back a
cluster Id number.  Now it goes to that cluster, and it looks up
object ID number 123 in the cluster's "containers" map, and it
discovers that there is no entry there.  So it concludes that even
though there was an entry in the ID table for 123, 123 has been deleted.
That is, you'd modify WizardStore.containerForId, near the end where
it calls cluster.containerForId, and check to see whether cluster.containerForId
returned null.

I haven't thought this through carefully enough to be sure that it works,
but I think something along these lines might work.

>
>
> > > Daniel, it seems that you know much about concurrency problems and stuff like
> > > that.
> >
> > Well, I've spent a lot of time on this stuff.  I was one of the original
> > designers of ObjectStore (and one of the founders of Object Design).
> > I was also one of the designers of PSE Pro for Java; I see from the
> > "samples" directory in the Ozone distribution that you've run into it.
>
> Wow! I was already wondering how you got familiar with my code that fast ;)
>
> Daniel, you had a look into the code and you found some pitfals very fast.
> I'm very interested in your opinion about design, architecture, code style,
> whatever pops up in your mind regarding ozone. Please be totally honest.

The code style is really good.  It's all very well-modularized.  The names
are clearly chosen, the organization is consistent, there are comments in the
right places, and so on.

There are several areas in which I wonder whether the performance could
be improved. I am hesitant to comment on this because the main thing I
have learned about performance improvement during my career is that
you should always start by doing actual benchmarking, measurement, and
analysis. I am always telling my colleagues what a bad idea it is to start
doing putative performance optimizations before you have actually measured
where the time is going.  Much more often than most people expect, you find
that the place where the time is going is not what you thought it would be.
You also have to choose your test cases (and benchmarks) carefully: how
are your users really using the system and what do they really care about?
The hard part here is to try to characterize "typical" users, since unfortunately
the users of a database system, especially an object-oriented database system,
tend to all be rather different from one another.

That said, here's one thing that occurred to me.

If I understand the code properly, at the time we commit a transaction,
we always load all the clusters that contain at least one object that we
have accessed during the transaction. This means we even load cluster
C if we have only read objects from C, and not modified any objects in
C.   Only after we have loaded the cluster do we test whether the cluster
was modified (write-locked); if it wasn't modified, we have loaded it for
nothing.

It seems that it might be worth considering making a memory-versus-time
tradeoff here.  Inside the Java VM, we cold keep track of which clusters
have been write-locked during the transaction, so that it would not be
necessary to read in the clusters that had only been read.  It seems that
in cases of transactions that read a lot of objects but only modify a few
objects, this could improve commit performance noticably.  (Of course
it would only matter if the number of clusters accessed by all the
running transactions was large enough to cause cache replacement
to happen; if there are few enough clusters being accessed that they
all always stay loaded, it makes no difference.)

In fact, if I understand correctly, by keeping that information in the Java VM,
we could eliminate the ".lock" files entirely.

The downside would appear in cases where there were so many clusters
that even storing such a small amount of information in the VM for each
cluster would use up an unacceptably large amount of Java VM object
space.

So it all depends on the nature of the workload, the anticipated sizes of
the databases, etc.

>
>
> >
> >
> > > Are you interested in helping with the development of a new and robust
> > > basis that handles concurrency and related things in ozone?
> >
> > I'm not in a position to be able to devote a serious amount of time to it,
> > mainly because I still have a full-time "day job" at the company, which is
> > now called eXcelon.  (I don't actually work on the OODBMS any more;
> > these days I'm doing an XML B2B integration server product.)  But I'm
> > happy to discuss it.
>
> Well, it's a commonplace, but we all, including me, have full-time "day job"s at
> the company. I'm CEO of a small german company...
>
> Anyway, hearing your ideas and comments is better than nothing. (for now ;)
>
> Just for curiousity, "XML B2B integration server product" sounds like you are
> competing with Intershop's enfinity, right?

It's such a new field that the products don't fall into clearly-defined genres
yet; what we're doing partially overlaps with what a lot of other companies
are doing. I actually hadn't heard of Intershop before, but the product marketing
people might have.

>
>
> And ones again just for Just for curiousity ;) how much of the ObjectStore
> technology is used to make excelons XML database? We have an XML layer for
> ozone too...

The product that we currently call "the eXcelon B2B Portal Server" (there
are some name changes coming soon) is based entirely on ObjectStore.
We originally bought the core of the XML DOM representation from
another company; in Release 3.0 (coming out in a few days), we've
rewritten it completely to be more compact and fast.

>
> > >
> > > We did not use this approach because it assumes that hashCode()/equals() is
> > > properly implemented for each and every object
> >
> > Oh, sorry, I should have said that what I was suggesting was to use an
> > identity-based hash table, not an equality-based hash table.  That is,
> > you use System.identityHashCode to get the hash values, and use
> > == to check for equality.  After all, you would not really want to use
> > "equals()" since if you had two distinct objects that were mutable and
> > equal, you would not want them to appear to be the same object.
>
> Ahh yes, makes sense. Thanks for your help here. However, I'm not sure if and
> when this gets implemented :(
>

Yeah, I'm sure this is far from the most important thing to work on!

-- Dan