Bug Description
RocksDbSettings.getOptionsByDbName() creates and attaches an empty BlockBasedTableConfig before applying the table-level setters. setTableFormatConfig() materializes the native RocksDB table factory at that point; subsequent changes to the Java BlockBasedTableConfig do not update that native factory.
As a result, blocksize, the shared block cache, index/filter caching, L0 index/filter pinning, and the Bloom filter are represented as configured in Java but are ineffective in native RocksDB. The configuration is therefore misleading and does not produce the behavior implied by the setters.
Environment
Network
Mainnet replay.
Software Versions
OS: Amazon Linux on c6g.4xlarge
JVM: OpenJDK 17
Git Commit: implementation under test from this issue
Version: N/A
Code: java-tron
Configuration
The replay used a snapshot at block height 83,835,006, a 500-block input, and a gp3 volume limited to 7,500 IOPS. The relevant code attaches new BlockBasedTableConfig() before invoking setBlockSize, setBlockCache, setCacheIndexAndFilterBlocks, setPinL0FilterAndIndexBlocksInCache, and setFilter.
Expected Behavior
Table-level configuration must either be applied to the native RocksDB table factory or explicitly retained as inactive for compatibility. Existing effective Options-level settings must remain unchanged.
The pre-change effective native table behavior is:
| Native option |
Expected effective value |
block_size |
4 KiB |
| Block cache |
RocksDB default, independent 8 MiB cache per database |
cache_index_and_filter_blocks |
false |
pin_l0_filter_and_index_blocks_in_cache |
false |
filter_policy |
nullptr |
whole_key_filtering |
true |
block_restart_interval |
16 |
Actual Behavior
The setters run after native table-factory materialization and do not affect the native OPTIONS-* configuration. In particular, the configured blocksize does not change the native block_size; the shared 1 GiB cache, index/filter cache, L0 pinning, and Bloom filter do not take effect.
Directly reordering the code activates several formerly inactive options simultaneously and is not a safe correction. The replay observed the following results:
| Configuration under test |
Throughput |
Change vs pre-change effective configuration |
| Pre-change effective native settings |
2.421 blocks/s |
Baseline |
| Previously inactive settings activated, first run |
1.969 blocks/s |
-18.67% |
| Previously inactive settings activated, repeat run |
1.680 blocks/s |
-30.61% |
| Compatibility path restoring pre-change native Options |
2.418 blocks/s |
-0.12% |
The direct-activation runs saturated available IOPS and increased average DB Get latency from about 0.205 ms to 0.325 ms and 0.420 ms. They simultaneously changed block size from 4 KiB to 64 KiB, enabled a 10-bit Bloom filter, index/filter caching, L0 pinning, the shared cache, and additional LSM settings; no single option can be assigned as the cause.
Additional screening did not justify enabling the settings by default: a shared 1 GiB cache reduced throughput by 4.0%; account Bloom improved 4.32%, below the 5% independent-confirmation threshold; and account-asset Bloom results were workload-specific (16.9% with 27.7% TRC10 traffic, 2.88% with 11.26%).
Frequency
Steps to Reproduce
- Create
BlockBasedTableConfig and pass it to options.setTableFormatConfig().
- Invoke the table setters afterward, as in
RocksDbSettings.getOptionsByDbName().
- Open a fresh RocksDB database and inspect its
OPTIONS-* file; the native table settings remain at the effective defaults above rather than the values set afterward in Java.
Logs and Error Messages
No exception is required. The observable failure is the mismatch between the Java configuration object and native OPTIONS-* output.
Additional Context (Optional)
Related Issues
None.
Possible Solution
Preserve the effective pre-change behavior rather than moving setTableFormatConfig() after the setters:
- Retain
blocksize in config.conf and reference.conf for compatibility; document in reference.conf that it is currently not applied to native table options.
- Retain its code-level field, default, accessor, builder, initialization parameter, and logging, but do not apply it to the native table factory.
- Remove the ineffective table setter sequence and retain
options.setTableFormatConfig(new BlockBasedTableConfig()).
- Retain the current static 1 GiB
LRUCache object and getCache() accessor for separate lifecycle and configuration work; the capacity limit is not eager physical allocation and the cache is not attached on the effective path.
- Evaluate future table-level tuning independently, with native
OPTIONS-* evidence.
Acceptance criteria:
Bug Description
RocksDbSettings.getOptionsByDbName()creates and attaches an emptyBlockBasedTableConfigbefore applying the table-level setters.setTableFormatConfig()materializes the native RocksDB table factory at that point; subsequent changes to the JavaBlockBasedTableConfigdo not update that native factory.As a result,
blocksize, the shared block cache, index/filter caching, L0 index/filter pinning, and the Bloom filter are represented as configured in Java but are ineffective in native RocksDB. The configuration is therefore misleading and does not produce the behavior implied by the setters.Environment
Network
Mainnet replay.
Software Versions
Configuration
The replay used a snapshot at block height
83,835,006, a 500-block input, and a gp3 volume limited to 7,500 IOPS. The relevant code attachesnew BlockBasedTableConfig()before invokingsetBlockSize,setBlockCache,setCacheIndexAndFilterBlocks,setPinL0FilterAndIndexBlocksInCache, andsetFilter.Expected Behavior
Table-level configuration must either be applied to the native RocksDB table factory or explicitly retained as inactive for compatibility. Existing effective Options-level settings must remain unchanged.
The pre-change effective native table behavior is:
block_sizecache_index_and_filter_blocksfalsepin_l0_filter_and_index_blocks_in_cachefalsefilter_policynullptrwhole_key_filteringtrueblock_restart_intervalActual Behavior
The setters run after native table-factory materialization and do not affect the native
OPTIONS-*configuration. In particular, the configuredblocksizedoes not change the nativeblock_size; the shared 1 GiB cache, index/filter cache, L0 pinning, and Bloom filter do not take effect.Directly reordering the code activates several formerly inactive options simultaneously and is not a safe correction. The replay observed the following results:
The direct-activation runs saturated available IOPS and increased average DB Get latency from about 0.205 ms to 0.325 ms and 0.420 ms. They simultaneously changed block size from 4 KiB to 64 KiB, enabled a 10-bit Bloom filter, index/filter caching, L0 pinning, the shared cache, and additional LSM settings; no single option can be assigned as the cause.
Additional screening did not justify enabling the settings by default: a shared 1 GiB cache reduced throughput by 4.0%;
accountBloom improved 4.32%, below the 5% independent-confirmation threshold; andaccount-assetBloom results were workload-specific (16.9% with 27.7% TRC10 traffic, 2.88% with 11.26%).Frequency
Steps to Reproduce
BlockBasedTableConfigand pass it tooptions.setTableFormatConfig().RocksDbSettings.getOptionsByDbName().OPTIONS-*file; the native table settings remain at the effective defaults above rather than the values set afterward in Java.Logs and Error Messages
Additional Context (Optional)
Related Issues
None.
Possible Solution
Preserve the effective pre-change behavior rather than moving
setTableFormatConfig()after the setters:blocksizeinconfig.confandreference.conffor compatibility; document inreference.confthat it is currently not applied to native table options.options.setTableFormatConfig(new BlockBasedTableConfig()).LRUCacheobject andgetCache()accessor for separate lifecycle and configuration work; the capacity limit is not eager physical allocation and the cache is not attached on the effective path.OPTIONS-*evidence.Acceptance criteria:
blocksizeand its API unchanged, document that it is inactive, and do not apply it to the native table factory.