Add Java API for rocksdb::CancelAllBackgroundWork() (#6657)
Summary: Adding a Java API for rocksdb::CancelAllBackgroundWork() so that the user can call this (when required) before closing the DB. This is to **prevent the crashes when manual compaction is running and the user decides to close the DB**. Calling CancelAllBackgroundWork() seems to be the recommended way to make sure that it's safe to close the DB (according to RocksDB FAQ: https://github.com/facebook/rocksdb/wiki/RocksDB-FAQ#basic-readwrite). Pull Request resolved: https://github.com/facebook/rocksdb/pull/6657 Reviewed By: cheng-chang Differential Revision: D20896395 Pulled By: pdillinger fbshipit-source-id: 8a8208c10093db09bd35db9af362211897870d96
This commit is contained in:
parent
e5f1bfc263
commit
487ebe4fd5
@ -2610,6 +2610,17 @@ jobjectArray Java_org_rocksdb_RocksDB_compactFiles(
|
|||||||
return ROCKSDB_NAMESPACE::JniUtil::toJavaStrings(env, &output_file_names);
|
return ROCKSDB_NAMESPACE::JniUtil::toJavaStrings(env, &output_file_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_RocksDB
|
||||||
|
* Method: cancelAllBackgroundWork
|
||||||
|
* Signature: (JZ)V
|
||||||
|
*/
|
||||||
|
void Java_org_rocksdb_RocksDB_cancelAllBackgroundWork(
|
||||||
|
JNIEnv*, jobject, jlong jdb_handle, jboolean jwait) {
|
||||||
|
auto* db = reinterpret_cast<ROCKSDB_NAMESPACE::DB*>(jdb_handle);
|
||||||
|
rocksdb::CancelAllBackgroundWork(db, jwait);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_rocksdb_RocksDB
|
* Class: org_rocksdb_RocksDB
|
||||||
* Method: pauseBackgroundWork
|
* Method: pauseBackgroundWork
|
||||||
|
@ -3479,6 +3479,17 @@ public class RocksDB extends RocksObject {
|
|||||||
compactionJobInfo == null ? 0 : compactionJobInfo.nativeHandle_));
|
compactionJobInfo == null ? 0 : compactionJobInfo.nativeHandle_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will cancel all currently running background processes.
|
||||||
|
*
|
||||||
|
* @param wait if true, wait for all background work to be cancelled before
|
||||||
|
* returning.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void cancelAllBackgroundWork(boolean wait) {
|
||||||
|
cancelAllBackgroundWork(nativeHandle_, wait);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will wait until all currently running background processes
|
* This function will wait until all currently running background processes
|
||||||
* finish. After it returns, no background process will be run until
|
* finish. After it returns, no background process will be run until
|
||||||
@ -4457,6 +4468,8 @@ public class RocksDB extends RocksObject {
|
|||||||
final int outputLevel,
|
final int outputLevel,
|
||||||
final int outputPathId,
|
final int outputPathId,
|
||||||
final long compactionJobInfoHandle) throws RocksDBException;
|
final long compactionJobInfoHandle) throws RocksDBException;
|
||||||
|
private native void cancelAllBackgroundWork(final long handle,
|
||||||
|
final boolean wait);
|
||||||
private native void pauseBackgroundWork(final long handle)
|
private native void pauseBackgroundWork(final long handle)
|
||||||
throws RocksDBException;
|
throws RocksDBException;
|
||||||
private native void continueBackgroundWork(final long handle)
|
private native void continueBackgroundWork(final long handle)
|
||||||
|
@ -1084,6 +1084,57 @@ public class RocksDBTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void continueBackgroundWorkAfterCancelAllBackgroundWork() throws RocksDBException {
|
||||||
|
final int KEY_SIZE = 20;
|
||||||
|
final int VALUE_SIZE = 300;
|
||||||
|
try (final DBOptions opt = new DBOptions().
|
||||||
|
setCreateIfMissing(true).
|
||||||
|
setCreateMissingColumnFamilies(true);
|
||||||
|
final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions()
|
||||||
|
) {
|
||||||
|
final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
|
||||||
|
Arrays.asList(
|
||||||
|
new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
|
||||||
|
new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
|
||||||
|
// open the database
|
||||||
|
try (final RocksDB db = RocksDB.open(opt,
|
||||||
|
dbFolder.getRoot().getAbsolutePath(),
|
||||||
|
columnFamilyDescriptors,
|
||||||
|
columnFamilyHandles)) {
|
||||||
|
try {
|
||||||
|
db.cancelAllBackgroundWork(true);
|
||||||
|
try {
|
||||||
|
db.put(new byte[KEY_SIZE], new byte[VALUE_SIZE]);
|
||||||
|
db.flush(new FlushOptions().setWaitForFlush(true));
|
||||||
|
fail("Expected RocksDBException to be thrown if we attempt to trigger a flush after" +
|
||||||
|
" all background work is cancelled.");
|
||||||
|
} catch (RocksDBException ignored) { }
|
||||||
|
} finally {
|
||||||
|
for (final ColumnFamilyHandle handle : columnFamilyHandles) {
|
||||||
|
handle.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cancelAllBackgroundWorkTwice() throws RocksDBException {
|
||||||
|
try (final Options options = new Options().setCreateIfMissing(true);
|
||||||
|
final RocksDB db = RocksDB.open(options,
|
||||||
|
dbFolder.getRoot().getAbsolutePath())
|
||||||
|
) {
|
||||||
|
// Cancel all background work synchronously
|
||||||
|
db.cancelAllBackgroundWork(true);
|
||||||
|
// Cancel all background work asynchronously
|
||||||
|
db.cancelAllBackgroundWork(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pauseContinueBackgroundWork() throws RocksDBException {
|
public void pauseContinueBackgroundWork() throws RocksDBException {
|
||||||
try (final Options options = new Options().setCreateIfMissing(true);
|
try (final Options options = new Options().setCreateIfMissing(true);
|
||||||
|
Loading…
Reference in New Issue
Block a user