Fix exception on RocksDB.getColumnFamilyMetaData() (#12474)

Summary:
https://github.com/facebook/rocksdb/issues/12466 reported a bug when `RocksDB.getColumnFamilyMetaData()` is called on an existing database(With files stored on disk). As neilramaswamy mentioned, this was caused by https://github.com/facebook/rocksdb/issues/11770 where the signature of `SstFileMetaData` constructor was changed, but JNI code wasn't updated.

This PR fix JNI code, and also properly populate `fileChecksum` on `SstFileMetaData`.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12474

Reviewed By: jowlyzhang

Differential Revision: D55811808

Pulled By: ajkr

fbshipit-source-id: 2ab156f41eaf4a4f30c49e6df421b61e8451230e
This commit is contained in:
Radek Hubner 2024-04-05 13:55:18 -07:00 committed by Facebook GitHub Bot
parent 7dcd0bd833
commit a8035ebc0b
2 changed files with 43 additions and 2 deletions

View File

@ -7740,7 +7740,8 @@ class SstFileMetaDataJni : public JavaClass {
}
jmethodID mid = env->GetMethodID(
jclazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ)V");
jclazz, "<init>",
"(Ljava/lang/String;Ljava/lang/String;JJJ[B[BJZJJ[B)V");
if (mid == nullptr) {
// exception thrown: NoSuchMethodException or OutOfMemoryError
return nullptr;
@ -7780,6 +7781,17 @@ class SstFileMetaDataJni : public JavaClass {
return nullptr;
}
jbyteArray jfile_checksum = ROCKSDB_NAMESPACE::JniUtil::copyBytes(
env, sst_file_meta_data->file_checksum);
if (env->ExceptionCheck()) {
// exception occurred creating java string
env->DeleteLocalRef(jfile_name);
env->DeleteLocalRef(jpath);
env->DeleteLocalRef(jsmallest_key);
env->DeleteLocalRef(jlargest_key);
return nullptr;
}
jobject jsst_file_meta_data = env->NewObject(
jclazz, mid, jfile_name, jpath,
static_cast<jlong>(sst_file_meta_data->size),
@ -7788,13 +7800,14 @@ class SstFileMetaDataJni : public JavaClass {
jlargest_key, static_cast<jlong>(sst_file_meta_data->num_reads_sampled),
static_cast<jboolean>(sst_file_meta_data->being_compacted),
static_cast<jlong>(sst_file_meta_data->num_entries),
static_cast<jlong>(sst_file_meta_data->num_deletions));
static_cast<jlong>(sst_file_meta_data->num_deletions), jfile_checksum);
if (env->ExceptionCheck()) {
env->DeleteLocalRef(jfile_name);
env->DeleteLocalRef(jpath);
env->DeleteLocalRef(jsmallest_key);
env->DeleteLocalRef(jlargest_key);
env->DeleteLocalRef(jfile_checksum);
return nullptr;
}
@ -7803,6 +7816,7 @@ class SstFileMetaDataJni : public JavaClass {
env->DeleteLocalRef(jpath);
env->DeleteLocalRef(jsmallest_key);
env->DeleteLocalRef(jlargest_key);
env->DeleteLocalRef(jfile_checksum);
return jsst_file_meta_data;
}

View File

@ -1423,6 +1423,33 @@ public class RocksDBTest {
}
}
@Test
public void getColumnFamilyMetadataWithChecksum() throws RocksDBException {
final Properties props = new Properties();
props.put("file_checksum_gen_factory", "FileChecksumGenCrc32cFactory");
final String dbPath = dbFolder.getRoot().getAbsolutePath();
try (final DBOptions dbOptions = DBOptions.getDBOptionsFromProps(props);
final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions();
final Options options = new Options(dbOptions, cfOptions).setCreateIfMissing(true)) {
try (final RocksDB db = RocksDB.open(options, dbPath);
final WriteOptions writeOptions = new WriteOptions().setDisableWAL(true)) {
db.put("key".getBytes(UTF_8), "value".getBytes(UTF_8));
}
try (final RocksDB db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath())) {
ColumnFamilyMetaData metadata = db.getColumnFamilyMetaData(); // Exception here
List<LevelMetaData> levels = metadata.levels();
assertThat(levels).isNotEmpty();
List<SstFileMetaData> filesMetadata = levels.get(0).files();
assertThat(filesMetadata).isNotEmpty();
assertThat(filesMetadata.get(0).fileChecksum()).isNotNull();
assertThat(filesMetadata.get(0).fileChecksum()).hasSize(4);
assertThat(filesMetadata.get(0).fileChecksum()).isNotEqualTo(new byte[] {0, 0, 0, 0});
}
}
}
@Ignore("TODO(AR) re-enable when ready!")
@Test
public void compactFiles() throws RocksDBException {