WriteBatch construction with explicit column-family handles is about 3.8% slower after 15873b1f
I followed up on commit 15873b1f in my machine, comparing the unmodified commit with its immediate parent. In measurements collected on September 12, 2026, construction of WriteBatch objects across 20 column families took 3.799% longer [95% CI: 3.519%, 4.079%], with after slower in all 16 confirmation pairs. This is a constructed batch-construction workload, not an exact reproduction of the original BackupEngine loop or a claim about complete DB::Write performance.
Environment and measurement
The machine has two Intel Xeon Gold 6430 CPUs, 64 physical cores and 128 logical CPUs, and runs Ubuntu 22.04, Linux 5.15.130-0515130-generic, glibc 2.35 and GCC 11.4. Data directories were on NVMe. The measured thread was pinned to logical CPU 17; the orchestration process used CPU 13. The governor was performance, Turbo was enabled, and frequency was not locked. This was a shared host, not an isolated machine; a running rshim service consumed approximately one CPU and was not stopped or repinned.
Both sides used unmodified static libraries built with the same Make options:
make -C "$SOURCE" -j32 static_lib DEBUG_LEVEL=0 PORTABLE=1 \
DISABLE_WARNING_AS_ERROR=1 CC=gcc-11 CXX=g++-11The library's release optimization level was -O2; the test programs used -O3 -DNDEBUG -fno-rtti -std=c++17 and linked against their respective revision's headers and static library. The tested snapshots identify themselves as 10.1.0. These are tested source revisions, not a claim that every release with those version numbers is affected.
After screening, the selected workload received 16 new confirmation pairs. Within each pair, the versions ran serially in alternating before/after and after/before order, each with a fresh database. Screening samples were not pooled with confirmation samples. Means below are arithmetic means; percentage changes are geometric means of paired after/before ratios, with two-sided 95% Student t intervals calculated on the log ratios. These intervals describe within-host repeatability, not variation across machines. All confirmation pairs are included in the attached CSV files.
Workload and results
- Before:
da8eba8b4927ae92be24b4dab3417187ca979d66 - After:
15873b1fdd3a4aa7a21825616623e4fb482443e7(New CF option disallow_memtable_writes, #13431) - Component:
WriteBatch::Putwith an explicitColumnFamilyHandle.
The workload creates the default column family and 19 ordinary column families, then precomputes 2,000,000 keys in key_exit:%09d format, numbered from 0 to 1,999,999. Each value contains 16 v bytes. No column family has disallow_memtable_writes enabled; this test uses the normal memtable, not VectorRep.
The timed loop constructs and retains WriteBatch objects, adding 256 records per batch with Put(handles[j % 20], keys[j], value). There are 7,813 batches; the last contains 128 records. The holding vector is reserved before timing. Timing includes batch allocation, record insertion and retaining the batches, but excludes key generation, database/column-family creation, DB::Write, destruction and verification.
| Metric | Before mean | After mean | Paired change | 95% confidence interval |
|---|---|---|---|---|
| Construction elapsed time | 0.125328 s | 0.130089 s | +3.799% | [+3.519%, +4.079%] |
| Process CPU time | 0.125300 s | 0.130074 s | +3.810% | [+3.535%, +4.086%] |
After was slower in 16/16 confirmation pairs, with every pair exceeding 3%. The corresponding construction-throughput change is -3.660%. This does not mean complete database writes are 3.8% slower. In separate confirmation workloads using VectorRep, complete batched writes slowed by 1.496% with 20 column families and 0.624% with 256 column families. The original repeated BackupEngine open/create-backup/destroy workload did not show a stable regression in the previous rerun.
After timing, the program applies every retained batch to the database, checks a sequence-number increase of exactly 2,000,000, verifies every key and value, flushes all column families, closes/reopens the database and verifies everything again. The post-timing writes disable WAL and are flushed to SST before reopening; this is a correctness check, not a measurement of durable-write latency.
The commit adds a disallow_memtable_writes check in WriteBatchInternal::GetColumnFamilyIdAndTimestampSize(). Each explicit-handle Put in this workload reaches that path even though the option remains false. The additional MemTableInserter check is outside this test's timed region. This narrows the observation to batch construction containing the new column-family check, but I have not performed an ablation that attributes the entire difference to that check. It also measures a different scope from the full-write db_bench test in the commit description.
The exact tested program is attached as upstream-attachments-20260913/rocks_focus.cc. After building it as described below, a single trial is:
taskset -c 17 "$BINARY" "$RUN" batch-only 2000000 256 20 1 1 off 0 1$RUN must be a new trial directory. The program creates its dataset itself; no external database snapshot is required. The printed seconds field, not the duration of the whole process, is the measured construction time.
Building the attached test program
Use separate clean source trees for the before and after commits listed above. Set $SOURCE to the relevant checkout, $HARNESS to the attached .cc file and $BINARY to a distinct output executable. The test program for this workload is rocks_focus.cc. The tested link command was:
g++-11 -std=c++17 -O3 -DNDEBUG -fno-rtti -I"$SOURCE/include" \
"$HARNESS" "$SOURCE/librocksdb.a" \
-pthread -ldl -lrt -lsnappy -lz -lbz2 -lzstd -o "$BINARY"Use matching development libraries on both sides; build metadata in the attachment records the detected features. Run versions serially and counterbalance their order, rather than comparing one before run with one after run. These commands reproduce the workload; recompilation on another machine is not expected to reproduce the archived executable hashes or identical percentages.
Attachments
rocksdb-15873b1f-attachments-20260913.tar.gz
rocksdb-15873b1f-attachments-20260913.tar.gz
contains this commit's standalone reports and supporting material:
- The exact tested
rocks_focus.cc, copied without modification. - Native result JSON, program output, command and property records for all 32 construction-confirmation runs, plus the 16-pair CSV.
- Construction-confirmation statistics, original summary objects for the same commit's full-write controls, independently recalculated construction statistics, the relevant commit diff, build provenance and environment information.
- A commit-specific provenance record, checksum manifest and evidence verification record.
The historical-scripts directory preserves original orchestration scripts as provenance; their historical paths are not prerequisites for running the C++ workload described here. This standalone bundle does not require another report or attachment, and excludes database directories and binaries. No sampled flamegraphs were collected for this case.
Source: facebook/rocksdb