facebook / rocksdb

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

the wiki “RocksJava-Basics” should be updated #12202

Open 404921490 opened 8 months ago

404921490 commented 8 months ago

The wiki says that column family handles need to be closed before freeing the db, but in reality, CF will be closed when DB is closed:

public void close() {
    for (final ColumnFamilyHandle columnFamilyHandle : ownedColumnFamilyHandles) {
      columnFamilyHandle.close();
    }
    ownedColumnFamilyHandles.clear();

    if (owningHandle_.compareAndSet(true, false)) {
      try {
        closeDatabase(nativeHandle_);
      } catch (final RocksDBException e) {
        // silently ignore the error report
      } finally {
        disposeInternal();
      }
    }
  }
import org.rocksdb.RocksDB;
import org.rocksdb.Options;
...
    // a static method that loads the RocksDB C++ library.
    RocksDB.loadLibrary();

    try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions().optimizeUniversalStyleCompaction()) {

      // list of column family descriptors, first entry must always be default column family
      final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
          new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts),
          new ColumnFamilyDescriptor("my-first-columnfamily".getBytes(), cfOpts)
      );

      // a list which will hold the handles for the column families once the db is opened
      final List<ColumnFamilyHandle> columnFamilyHandleList =
          new ArrayList<>();

      try (final DBOptions options = new DBOptions()
          .setCreateIfMissing(true)
          .setCreateMissingColumnFamilies(true);
           final RocksDB db = RocksDB.open(options,
               "path/to/do", cfDescriptors,
               columnFamilyHandleList)) {

        try {

          // do something

        } finally {

          // NOTE frees the column family handles before freeing the db
          for (final ColumnFamilyHandle columnFamilyHandle :
              columnFamilyHandleList) {
            columnFamilyHandle.close();
          }
        } // frees the db and the db options
      }
    } // frees the column family options
...
adamretter commented 8 months ago

The wiki says that column family handles need to be closed before freeing the db

That is true. They do need to be closed.

but in reality, CF will be closed when DB is closed:

In more recent versions of RocksDB, we added some house-keeping code behind the scenes to catch this and close them if the user had not already done so themselves.

I don't think that there will be a problem if the user closes them, and then we attempt to close them again. So I think the current advice stands for all versions of RocksJava - or am I mistaken?

ajkr commented 8 months ago

7428 I guess. We could clarify on the wiki that it shows a suggested shutdown procedure, not a required one. Otherwise people who aren't following the procedure may think something bad will happen when they read the wiki (resource leak, unclean shutdown, etc.). But AFAIK there is no such risk