facebook / rocksdb

A library that provides an embeddable, persistent key-value store for fast storage.
http://rocksdb.org
GNU General Public License v2.0
27.86k stars 6.2k forks source link

JNI Exception from calling getColumnFamilyMetaData twice #12466

Open neilramaswamy opened 3 months ago

neilramaswamy commented 3 months ago

Expected behavior

After writing some data to a database, calling getColumnFamilyMetaData twice should not throw an exception in either case.

Actual behavior

After writing some data to a database, the second call to getColumnFamilyMetaData throws the following JNI exception:

Exception in thread "main" java.lang.NoSuchMethodError: <init>
        at org.rocksdb.RocksDB.getColumnFamilyMetaData(Native Method)
        at org.rocksdb.RocksDB.getColumnFamilyMetaData(RocksDB.java:4439)
        at org.rocksdb.RocksDB.getColumnFamilyMetaData(RocksDB.java:4449)

Steps to reproduce the behavior

This consistently repro's with both JDK 8 and 17. I bisected the test, and it only appeared in 8.11.3, and persists in 9.0.0. However, 8.10.2 does not have this issue. Here is the most minimal repro I could create:

public class Repro {
    private static String DB_PATH = "/tmp/rocks-db";

    public static void main(String[] args) {
        Options opts = new Options();
        opts.setCreateIfMissing(true);

        try (final RocksDB db = RocksDB.open(opts, DB_PATH)) {
            db.put("foo".getBytes(), "bar".getBytes());
            db.close();
        } catch (final RocksDBException e) {
            System.err.println(e);
        }

        try (final RocksDB db = RocksDB.open(opts, DB_PATH)) {
            db.getColumnFamilyMetaData();
            db.getColumnFamilyMetaData(); // Exception here

            db.close();
            opts.close();
        } catch (final RocksDBException e) {
            System.err.println(e);
        }
    }
}

Interestingly, this issue does not appear if you have an empty database. Excluding the call to put("foo", "bar") on a clean directory will prevent this error from happening. Also, running the test without the put call (but with a database that has data in it) will also fail.

Thanks!

neilramaswamy commented 3 months ago

Update: I have bisected the issue to https://github.com/facebook/rocksdb/pull/11770/. I've looked through the PR and don't see anything obviously wrong that could be the root cause. (One thing I noticed was that this line does an exception check on the env, even though in that case we should check if it's a nullptr. But that's not the issue, since locally, that doesn't fix the error.)

rhubner commented 3 months ago

Hello @neilramaswamy,

I think you really found bug and you are right with the PR which cause this bug. It looks like JNI code for SstFileMetaData wasn't updated during this PR. Let me fix it.

Radek

neilramaswamy commented 3 months ago

Hi @rhubner, were you planning on opening a PR? If not, I can investigate whether the fix you proposed actually works (I haven't actually checked), and I can create one.

rhubner commented 3 months ago

Hi @rhubner, were you planning on opening a PR? If not, I can investigate whether the fix you proposed actually works (I haven't actually checked), and I can create one.

Hello @neilramaswamy,

I just submitted PR #12474 which should fix this issue. It will be great if you can test it and let me know the results.

Radek