xapian

Olly Betts olly at survex.com
Mon Sep 11 00:16:17 BST 2017


On Tue, Sep 05, 2017 at 11:31:22AM +0800, 李猛 wrote:
> Recently I get a new problem, this problem can result in JVM crashed. The
> situation is that there are some duplicate documents(the document data is
> duplicate, not the docId) in the database and the following is my filter
> method:
>     MSet mset=enquire.getMSet(0,10);//offeset,pagesize
>             MSetIterator mSetIterator=mset.begin();
>             while(mSetIterator.hasNext()){
>             if(docId!=0){
>                    LOGGER.info("before delete");
>                    LOGGER.info("Delete document
>    id="+mSetIterator.getDocId()+" this document is about                    
>                newsId="+mSetIterator.getDocument().getData()+"; query
>    newsId="+mnm.getNewsId());
>                   writableDatabase.deleteDocument(mSetIterator.getDocId());
>                   mSetIterator.next();
>                   continue;
>            }
>            docId = mSetIterator.getDocId();
>            LOGGER.info("docId:"+docId);
>           mSetIterator.next();
>    }
> The attachment is jvm crash log

Based on the code you've shown, I wouldn't expect such a crash, though
without seeing a complete reproducer it's hard to usefully comment -
the crash seems to be in the C++ get_doccount() method which isn't
called by the code you show explicitly (and I don't think it would be
implicitly either).

If you're able to cut this down to a self-contained example which shows
the crash, we can probably work out what's going on.

> and I do not call commit() method. My opinion is that Because the
> persistence to the hard disk is automatically generated, it is
> possible get_document () to get the deleted document. And I want to
> know that if I call commit(), the data is flushing into hard disk
> after the func is done? 

When you use a WritableDatabase object (as it seems you are above), then
any changes made are visible through that same object.  So this code
will fail on the getDocument() call because document #1234 no longer
exists in the view that writableDatabase has:

    writableDatabase.deleteDocument(1234);
    doc = writableDatabase.getDocument(1234);

However, the changes won't be visible to other Database objects open on
the database until you call commit() on the WritableDatabase (or until
enough changes are made to trigger an automatic commit - you can prevent
this if you want to by grouping changes using transactions).

Cheers,
    Olly



More information about the Xapian-devel mailing list