Skip to content

[Bug] Ineffective RocksDB table option setters #49

Description

@bladehan1

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

  • Always (100%)
  • Frequently (>50%)
  • Sometimes (10-50%)
  • Rarely (<10%)

Steps to Reproduce

  1. Create BlockBasedTableConfig and pass it to options.setTableFormatConfig().
  2. Invoke the table setters afterward, as in RocksDbSettings.getOptionsByDbName().
  3. 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:

  • Retain blocksize and its API unchanged, document that it is inactive, and do not apply it to the native table factory.
  • Remove the ineffective table setter sequence without activating it; retain the static cache for separate design and validation.
  • Verify with a fresh temporary database: 4 KiB blocks, no Bloom filter, and no L0 index/filter pinning.
  • Pass configuration tests, native Options tests, and Checkstyle.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions