Open-Source Wikis

/

etcd

/

Systems

/

Backend (bbolt)

etcd-io/etcd

Backend (bbolt)

Source: server/storage/backend/.

Purpose

The backend is etcd's interface to bbolt — the embedded B+tree-based key-value store that holds the MVCC keyspace, lease state, auth state, cluster metadata, and version markers. Everything that ends up on disk in <data-dir>/member/snap/db flows through this package.

Directory layout

server/storage/backend/
├── backend.go          # Backend interface, batchTxBuffer, defrag, snapshot
├── batch_tx.go         # Buffered write transactions
├── read_tx.go          # Read transactions w/ buffer overlay
├── tx_buffer.go        # In-memory write buffer flushed on commit
├── config_default.go / config_linux.go / config_windows.go
├── metrics.go
├── hooks.go            # Pre-commit hooks (used by mvcc and lease)
├── verify.go           # Debug-only invariants
└── testing/

Key abstractions

Symbol File Description
Backend interface server/storage/backend/backend.go Top-level API: BatchTx, ReadTx, Snapshot, Defrag, Hash, Commit
backend struct same file Owns the bbolt *bolt.DB, batch-tx, and metrics
BatchTx server/storage/backend/batch_tx.go Buffered write transaction: writes to a memory buffer, periodically commits to bolt
ReadTx server/storage/backend/read_tx.go Snapshot-isolated read view
txWriteBuffer / txReadBuffer server/storage/backend/tx_buffer.go Per-bucket in-memory mutation buffer
defragdbPath server/storage/backend/backend.go Where defrag's temporary file lives

How it works

sequenceDiagram
    participant Caller
    participant Batch as BatchTx
    participant Buf as txWriteBuffer
    participant Bolt as bbolt
    participant Disk

    Caller->>Batch: UnsafePut(bucket, key, value)
    Batch->>Buf: buffer mutation
    note over Batch: every BatchInterval (100ms) or BatchLimit (10000) ops
    Batch->>Bolt: bolt.Update(applyBuffer)
    Bolt->>Disk: fsync
    Bolt-->>Batch: ok
    Batch->>Buf: clear buffered mutations

Reads:

  1. ReadTx opens a bolt.Tx for the lifetime of the read.
  2. To produce consistent semantics across in-flight writes, the read side overlays the currently buffered writes from txWriteBuffer on top of the bolt view.

Defragmentation:

  1. Acquires the global write lock.
  2. Opens a new bolt file, walks every bucket and copies the compacted contents.
  3. Atomically renames the new file over the old one.

Configuration knobs

Flag / constant Default Effect
--quota-backend-bytes 0 (= 2 GiB) Triggers a NOSPACE alarm above this size
--backend-batch-interval 100 ms How often the batch tx commits if it's not full
--backend-batch-limit 10000 Op count threshold for early commit
--backend-bbolt-freelist-type array bbolt freelist type (Linux only)
MmapSize (config_linux.go) 1 GiB initial mmap region size; doubles as the DB grows

Integration points

  • mvcc writes to the key bucket through BatchTx.
  • lease writes to the lease bucket.
  • auth writes to auth, authUsers, authRoles buckets.
  • schema (server/storage/schema/) defines the bucket inventory and version metadata.
  • maintenance (server/etcdserver/api/v3rpc/maintenance.go) wires Snapshot, Defrag, HashKV, MoveLeader.
  • etcdutl and tools/etcd-dump-db/ open the same DB format directly.

Entry points for modification

  • Tuning batch behavior → config_default.go plus the --backend-batch-* flags in server/embed/config.go.
  • New bucket or column → server/storage/schema/bucket.go.
  • Reducing fsync pressure → look at BatchTx.Commit and bolt.DB.Sync.

Caveats

  • bbolt holds a single global write lock; long write transactions block all writers. The batch tx exists specifically to batch many small writes into one bolt commit.
  • A long-running read transaction prevents the freelist from growing, which can lead to tail-latency spikes; the apply pipeline takes care to close read txns promptly.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Backend (bbolt) – etcd wiki | Factory