[Xapian-devel] Xapian::Database->close() for perl missing

Olly Betts olly at survex.com
Thu Apr 19 23:46:20 BST 2012


On Thu, Apr 19, 2012 at 03:45:36PM +0200, Websuche :: Felix Ostmann wrote:
> I have a xapian-daemon, which can be queried via http. A background-process
> generated every hour one new index and then remove and create a new symlink
> to the current database.
> 
> /path/to/index/20120419010000
> /path/to/index/20120419020000
> /path/to/index/20120419030000
> /path/to/index/default => /path/to/index/20120419030000

Note that using symlinks for this isn't recommended - Xapian opens the
files using the given path, so if it is in the middle of opening the
database when you switch the symlink, it'll try to open half the old
one and half the new one, which isn't good at all.

It's better to use a stub database file instead.

> So the daemon only check the mtime of /path/to/index/default/iamchert befor
> every request and if it is a new one, he close/reopen the database.
> 
> The problem is: There is no ->close in perl for a database! So currently i
> override the object. After some days, the prozess have many open
> filepointers to allready removed databases.

If you destroy all references to the database, it should get closed, so
this suggests that either the Perl bindings aren't keeping track of the
references correctly, or there's an object you have around still with a
reference to the Database (keeping an Enquire or MSet or TermIterator or
similar will implicitly keep a reference to the database).

> I also tried ->reopen, but xapian dont reopen every file, so after reopen,
> i have some files opened from the old database and the record.DB from the
> new one. Also the filepointer to the old record.DB still exists (i tested
> with lsof -p $PID).

Calling reopen() will only update you to the latest revision of the
database you originally opened - it doesn't work through symlinks like
this (or through stub databases).

> So what is the right way to make a clean shutdown of a opened xapian
> database?

It should be enough to overwrite the perl variables which hold
references, e.g.:

$db = $enquire = $mset = undef;

Though it is quite easy to miss an object.  Or maybe there's a missing
unreference somewhere.

I thought we supported Database::close() in Perl, but it looks like when
the wrapper was contributed, it was put on WritableDatabase only, which
was wrong.  You can probably just copy the close bit from
XS/WritableDatabase.xs to XS/Database.xs if you want to fix it locally.
If you do, a patch would be great.  Otherwise I'll attend to it when I
have a bit more spare time.

Cheers,
    Olly



More information about the Xapian-devel mailing list