Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileDB gets corrupted after Thread.interrupt #235

Closed
vadimzv opened this issue Nov 12, 2013 · 1 comment
Closed

FileDB gets corrupted after Thread.interrupt #235

vadimzv opened this issue Nov 12, 2013 · 1 comment

Comments

@vadimzv
Copy link

vadimzv commented Nov 12, 2013

My application consumes data from external source and writes it to mapdb, this process happens in a separate thread and looks like this:

void run()
{
    while (isAlive)
    {
        Data data = retrieveData();
        if (data.isEmpty())
        {
            Thread.sleep(timeout);
        }
        else if (data.isExternalSystemUnavailable())
        {
            Thread.sleep(data.tillExternalSystemIsAvailable);
        }
        else
        {
            writeToMapDB(data);
        }
    }
}

When user stops application I'm calling thread.interrupt to interrupt all possible sleeps. But if in that moment writing to mapdb was in progress, I get the exception:

Caused by: java.io.IOError: java.nio.channels.ClosedByInterruptException
    at org.mapdb.Volume$FileChannelVol.getDataInput(Volume.java:784)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.StoreDirect.get2(StoreDirect.java:381)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.StoreDirect.get(StoreDirect.java:364)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.EngineWrapper.get(EngineWrapper.java:60)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.AsyncWriteEngine.get(AsyncWriteEngine.java:361)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.Caches$HashTable.get(Caches.java:213)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.BTreeMap.remove2(BTreeMap.java:906)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.BTreeMap.remove(BTreeMap.java:897)[214:mapdb:0.9.7.SNAPSHOT]
    at mhubdb.TableDB.put(TableDB.java:107)[197:mhubDB.mhubDB:1.0.0.SNAPSHOT]
Caused by: java.nio.channels.ClosedByInterruptException
    at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)[:1.7.0_25]
    at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:679)[:1.7.0_25]
    at org.mapdb.Volume$FileChannelVol.readFully(Volume.java:719)[214:mapdb:0.9.7.SNAPSHOT]
    at org.mapdb.Volume$FileChannelVol.getDataInput(Volume.java:781)[214:mapdb:0.9.7.SNAPSHOT]
    ... 61 more

And the whole data file gets corrupted. That's the error when I'm trying to read data file just after ClosedByInterruptException:

java.lang.RuntimeException: Writer thread failed
        at org.mapdb.AsyncWriteEngine.checkState(AsyncWriteEngine.java:290)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.AsyncWriteEngine.get(AsyncWriteEngine.java:354)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.Caches$HashTable.get(Caches.java:213)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastEntryRecur(BTreeMap.java:1319)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastEntryRecur(BTreeMap.java:1320)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastEntryRecur(BTreeMap.java:1320)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastEntry(BTreeMap.java:1293)[214:mapdb:0.9.7.SNAPSHOT]
        at mhubdb.TableDB.getLastRecord(TableDB.java:172)[197:mhubDB.mhubDB:1.0.0.SNAPSHOT]
Caused by: java.io.IOError: java.nio.channels.ClosedChannelException
        at org.mapdb.Volume$FileChannelVol.putData(Volume.java:703)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.StoreDirect.update2(StoreDirect.java:443)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.StoreDirect.update(StoreDirect.java:424)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.EngineWrapper.update(EngineWrapper.java:66)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.AsyncWriteEngine.access$101(AsyncWriteEngine.java:72)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.AsyncWriteEngine.runWriter(AsyncWriteEngine.java:206)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.AsyncWriteEngine$WriterRunnable.run(AsyncWriteEngine.java:156)[214:mapdb:0.9.7.SNAPSHOT]
        at java.lang.Thread.run(Thread.java:724)[:1.7.0_25]
Caused by: java.nio.channels.ClosedChannelException
        at sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:94)[:1.7.0_25]
        at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:691)[:1.7.0_25]
        at org.mapdb.Volume$FileChannelVol.writeFully(Volume.java:638)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.Volume$FileChannelVol.putData(Volume.java:701)[214:mapdb:0.9.7.SNAPSHOT]
        ... 7 more

And this is the error after I reinitialized db and tried to call BTreeMap.lastKey:

Caused by: java.lang.NullPointerException
        at org.mapdb.BTreeMap.lastEntryRecur(BTreeMap.java:1300)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastEntryRecur(BTreeMap.java:1320)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastEntryRecur(BTreeMap.java:1320)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastEntry(BTreeMap.java:1293)[214:mapdb:0.9.7.SNAPSHOT]
        at org.mapdb.BTreeMap.lastKey(BTreeMap.java:1469)[214:mapdb:0.9.7.SNAPSHOT]

Of course I can apply some synchronization trick on writeToMapDB to prevent simultaneous writeToMapDB and thread.interrupt. But is this behaviour of mapdb normal?

@jankotek
Copy link
Owner

Yes, it is expectable. FileChannel is closed if thread is interrupted during IO. First exception actually happened during read.

I could in theory check and reopen closed channels, but it seems like big performance overhead for narrow corner case.

It seems you use RAF mode, memory-mapped-files could perhaps handle interrupts, but I have no idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants