Skip to content

Values up to 2 MiB, page-slot reuse, and WAL frame cap - #1

Merged
ChromaBeast merged 2 commits into
mainfrom
ccr-c5e72350-yy7e7c
Oct 28, 2026
Merged

ChromaBeast merged 2 commits into
mainfrom
ccr-c5e72350-yy7e7c

Conversation

@ChromaBeast

Copy link
Copy Markdown
Owner

Summary

Values were capped at 4,000 bytes (one slotted-page tuple), so clients storing documents, reports or serialized aggregates had to invent their own chunking. This adds large values as a general engine feature and fixes two allocator defects found while testing it.

  • Large values (up to 2 MiB, batches up to 8 MiB). Values over MaxRecordSize are stored as a CRC-checked chain of chunk tuples headed by a 24-byte manifest; the B+ tree flags the manifest RID with bit 15 of the slot ID. Small values take the existing path unchanged and existing files need no migration. The WAL, recovery and replication still log whole values. Design and trade-offs: docs/adr/0001-large-values.md.
  • Corruption handling. Reads verify chunk magic, chain length and CRC (ErrCorruptValue); overwrite and delete free a chain only after it validates, so a damaged chain cannot tombstone other keys' tuples.
  • gRPC limits. api.MessageSizeServerOptions / api.MessageSizeDialOption raise the 4 MiB default; the server, followers and beastctl use them. Write-error status mapping moved into grpc_status.go.
  • WAL hardening. Frames over 32 MiB are refused on write, and a torn header claiming a huge length now reads as a torn tail instead of allocating up to 4 GiB.
  • Allocator fixes (pre-existing). InsertTuple never reused tombstoned slots, so a recycled page's slot directory grew until it couldn't host a full tuple; and pages too full for one request were dropped from the reuse list for good. 300 overwrites of a 512 KB value grew the file to 2,120 pages, now 266; 600 small overwrites added 264 pages, now 3.

Compatibility

  • Additive API; no protobuf changes. ErrRecordTooLarge now means "over 2 MiB"; ErrBatchTooLarge is new.
  • Downgrading after writing large values is not supported: an older binary reading such a key fails with ErrSlotOutOfBounds rather than returning manifest bytes.

Tests

Boundary sizes, overwrite/delete space reuse, crash and clean restart, CAS and batches on large values, scans, corruption detection, a mixed-size oracle across restarts, page slot reuse, oversized WAL headers, 6 MiB gRPC batches, and catch-up plus live replication of 2 MiB values. Full suite passes with -race; go vet clean.

Downstream: Peerline (ChromaBeast/Peerline) depends on this for releases, reports and indexes larger than 4 KB; its router tests pass against a live server built from this branch.


Generated by Claude Code

Values were capped at 4,000 bytes, one slotted-page tuple. Larger values (up
to MaxValueSize, 2 MiB) are now stored as a CRC-checked chain of chunk tuples
headed by a manifest; the B+ tree flags the manifest RID with bit 15 of the
slot ID. Small values take the existing path unchanged, existing files need no
migration, and the WAL, recovery and replication still log whole values.
Batches may carry up to 8 MiB of values. See docs/adr/0001-large-values.md.

- Reads verify chunk magic, chain length and CRC (ErrCorruptValue); overwrite
  and delete free a chain only after it validates.
- gRPC: MessageSizeServerOptions / MessageSizeDialOption raise the 4 MiB
  default; the server, followers and beastctl use them. Write-error status
  mapping is shared in grpc_status.go.
- WAL: frames over 32 MiB are refused on write, and a torn header claiming a
  huge length now reads as a torn tail instead of allocating up to 4 GiB.
- Storage: InsertTuple reuses tombstoned slots. Previously a recycled page's
  slot directory grew until it could not host a full tuple, and pages too full
  for one request were dropped from the reuse list; 300 overwrites of a 512 KB
  value grew the file to 2,120 pages, now 266, and 600 small overwrites added
  264 pages, now 3.

Tests: boundary sizes, overwrite/delete space reuse, crash and clean restart,
CAS and batches on large values, scans, corruption detection, a mixed-size
oracle across restarts, gRPC 6 MiB batches, and catch-up plus live replication
of 2 MiB values. Full suite passes with -race.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017mWMfRGkKdRgKc5mtSsWEG
Copilot AI balanced review requested due to automatic review settings October 28, 2026 17:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-28T17:30:10.115879Z 069adff PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 069adff0a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/api/engine_large.go Resolved
Comment thread internal/api/grpc_status.go Resolved
…g in batch limit

- freeValue checked chunk magic and chain termination but not total length
  or CRC, so a mis-linked chain that still ended cleanly after the right
  number of chunks could free tuples owned by another key. It now verifies
  length and CRC first and leaves a failing chain in place.
- MaxBatchBytes counted only value bytes. Each WAL batch operation adds 15
  bytes of framing, so many tiny puts could commit a WAL frame larger than
  the replication message limit, and followers could never catch up on it.
  The limit now covers the encoded frame.

Both reported by Codex review on #1; regression tests reproduce each.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017mWMfRGkKdRgKc5mtSsWEG
@ChromaBeast
ChromaBeast merged commit d8c1280 into main Oct 28, 2026
4 checks passed
ChromaBeast added a commit that referenced this pull request Nov 12, 2026
…g in batch limit

- freeValue checked chunk magic and chain termination but not total length
  or CRC, so a mis-linked chain that still ended cleanly after the right
  number of chunks could free tuples owned by another key. It now verifies
  length and CRC first and leaves a failing chain in place.
- MaxBatchBytes counted only value bytes. Each WAL batch operation adds 15
  bytes of framing, so many tiny puts could commit a WAL frame larger than
  the replication message limit, and followers could never catch up on it.
  The limit now covers the encoded frame.

Both reported by Codex review on #1; regression tests reproduce each.
ChromaBeast added a commit that referenced this pull request Nov 12, 2026
Values up to 2 MiB, page-slot reuse, and WAL frame cap
ChromaBeast added a commit that referenced this pull request Nov 13, 2026
Values up to 2 MiB, page-slot reuse, and WAL frame cap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants