On Tue, Jul 24, 2012 at 9:40 AM, Christian Grün
<christian.gr...@gmail.com>wrote:

> > Any insights on the issue with BaseX randomly locking databases and then
> > failing CREATE DB/ALTER DB operations?
>
> I noticed your mail, but it's difficult to give a general assumption
> on what might be the problem. I'm aware of many existing use cases in
> which databases are created and dropped, and queries are sent.
>
> As databass are implicitly locked if they are accessed by a client
> [1], you may need to explicitly close sessions in order to avoid that
> opened databases will not be properly closed.
>
>
I am very confused.  I never explicitly "open" a database. I use sessions
that issue a series of queries & commands, such as 'XQUERY', 'CREATE DB',
and the like.  I don't issue any 'OPEN' or 'CLOSE' commands.

I note that we are using the client/server architecture. A single server,
with multiple client sessions. Each client session issues 'XQUERY', etc.
commands via the org.basex.  Closing a session simply disconnects - why
should it have any effect on the db state?

Let me look at the code to illustrate the failure...

The message we're talking about is
org.basex.core.BaseXException: Database
'PUB_feed_libx_dot_editions_at_gmail_dot_com_core'
is currently opened by another client.

That's 'db_pinned_%' in your code...
DB_PINNED_X in Text.java...

Happens during createDB:

./src/main/java/org/basex/core/cmd/CreateDB.java:92:
 if(context.pinned(name)) return error(DB_PINNED_X, name);
./src/main/java/org/basex/core/cmd/CreateDB.java:152:
 if(ctx.pinned(name)) throw new BaseXException(DB_PINNED_X, name);
another client.

I'm guessing it's line 92.... Looking at context.pinned:

  public boolean pinned(final String db) {
    return datas.pinned(db) || TableDiskAccess.locked(db, this);
  }

Leads to Datas.java.... and TableDiskAccess.java
Datas.java simply records in memory which dbs are 'pinned' and how often.
TableDiskAccess.java does physical file locking.

Looking for calls to 'unpin' ... finds one in Close.java:

/**
 * Evaluates the 'close' command and closes the current database.
 *

So it appears that BaseX expects database accesses to be wrapped in a
OPEN...CLOSE brace.  We don't issue neither OPEN nor CLOSE... so I'm
guessing it's done internally as part of XQUERY?

Suppose one client run an XQUERY against a db, which involves (internally)
one or more 'OPEN' calls, then accesses, then 'CLOSE' commands --- how do
you synchronize this client with others?  Do you have a master lock so that
the server processes only one query/command at a time?

If so, that would be bad for performance... if not, your assumption that
you can throw an error in CreateDB.run if the db is pinned is wrong.
 Instead, you'll need a 'wait_until_unpinned' method that CreateDB calls
until the db it's trying to create is no longer pinned. It would need to
wait on a signaling device that's signaled in unpin(). (Note that we are
recreating a database with the same name over and over, even while some
clients perform XQUERY on the then-current version of that database.)  This
mode of failure would, in essence, be a race condition that would manifest
itself if there happened to be a read access to the db by one client while
another is trying to create a db with the same name.

I actually don't think that's the failure we're seeing, based on the fact
that restarting the server allows the operation to succeed. The latter
would point to not calling 'close()' on some path in a previous db
operation, leading to a stale entry in the datas. list.

 - Godmar

If you should manage to create a test case, that would be great.
> Christian
>
> [1] http://docs.basex.org/wiki/Transaction_Management#Locking
>
_______________________________________________
BaseX-Talk mailing list
BaseX-Talk@mailman.uni-konstanz.de
https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk

Reply via email to