TessariDBDocs
  • 0.35.3latest
  • 0.35.2
  • 0.35.1
  • 0.35.0
  • 0.34.4
  • 0.34.3-beta
  • 0.34.2-beta
  • 0.34.1-beta
  • 0.34.0-beta
  • 0.33.4-beta
  • 0.33.3-beta
  • 0.33.2-beta
  • 0.33.1-beta
  • 0.33.0-beta
  • 0.32.0-beta

Compaction and backpressure

Leveled, universal and FIFO compaction, parallel and rate-limited; manual compaction and bulk loads; and how writes slow down, then stop, when compaction falls behind.

Flushed tables land in level 0, where their key ranges may overlap. Compaction merges tables into fewer, larger, sorted ones. It drops versions no open snapshot can read and keys removed by deletes. Each keyspace picks its style with KeyspaceOptions::compaction.

Leveled (default)

Level 0 merges into levels below it. Each level holds tables with non-overlapping key ranges, so a read checks at most one table per level.

  • A compaction of level 0 starts at level0_compaction_trigger tables (4).
  • Level sizes are computed from the bottom up: data first goes to the bottom level, and the levels above fill as it grows. level_base_bytes (256 MiB) is the first level's target; each level is level_size_multiplier (10) times the one above.
  • Output tables close at target_file_bytes (64 MiB). A key's versions never span two tables.

Leveled gives few tables per read and little space beyond the live data. It pays for that by rewriting data once per level.

Universal

CompactionStyle::universal(). Every level-0 table is a sorted run, and so is the bottom level. Runs of similar size are merged, newest first. Everything is merged into the bottom once the runs above it hold max_size_amplification_percent (200) of its size.

Universal rewrites data fewer times than leveled. It pays in space — up to that bound beyond the live data, and twice the data during a full merge — and in more tables per read.

FIFO

CompactionStyle::fifo(). Tables stay in level 0 and are never merged. Once they hold more than max_table_bytes (1 GiB by default), the oldest are dropped.

FIFO suits data that may expire by age, such as metrics or caches. Data older than what fits is lost. A key reads its newest kept value or nothing, never an older one.

Parallel and paced

  • max_compactions (4) compactions of a keyspace run at once, each on tables and a key range no other running compaction touches. Level 0 is compacted by one at a time.
  • max_subcompactions (4): one compaction splits into up to this many key ranges, each merged on its own thread.
  • DbOptions::background_threads (4) threads run flushes and compactions.
  • DbOptions::compaction_bytes_per_second paces compaction output, so a merge does not starve foreground reads of disk bandwidth. Zero (the default) does not pace. Flushes are never paced: writes wait for them.

Manual compaction and bulk loads

Db::compact_range(keyspace, start, end) compacts a key range now.

For a bulk load, set disable_auto_compactions on the keyspace. The engine then starts no compaction of it by itself, and compact_range still runs. The level-0 slowdown and stop triggers still hold writes, so a load that reaches them needs a manual compaction to go on. KeyspaceOptions::bulk_load() is a preset for one large load: 512 MiB in-memory tables, up to six waiting for a flush, and 64 KiB blocks.

Backpressure: slow down, then stop

When compaction falls behind, writes slow down before they stop, so the engine never lets debt grow without bound.

SignalWrites slow down atWrites stop at
level-0 tableslevel0_slowdown_trigger (20)level0_stop_trigger (36)
bytes compaction owessoft_pending_compaction_bytes (64 GiB)hard_pending_compaction_bytes (256 GiB)
in-memory tables—the active table is full and max_immutable_memtables (2) frozen tables already wait for a flush

While slowed down, writes go at DbOptions::delayed_write_bytes_per_second (16 MiB/s): each write waits for its own bytes. A write with WriteOptions::no_slowdown fails with Error::WriteStalled instead of waiting. The time writes spent stalled is counted in the StallMicros statistic.