Skip to content

Fix reverse-bytewise reads with overlong common prefixes - #15525

Open
xgbtxy wants to merge 1 commit into
meta:mainfrom
xgbtxy:fix/reverse-prefix-15439
Open

xgbtxy wants to merge 1 commit into
meta:mainfrom
xgbtxy:fix/reverse-prefix-15439

Conversation

@xgbtxy

@xgbtxy xgbtxy commented Oct 30, 2026

Copy link
Copy Markdown

Summary

Fix stale values, missed keys, and deleted values reappearing when ReverseBytewiseComparator() is used with format 8 common-prefix optimization.

A non-restart internal key can share bytes with its predecessor beyond the end of its user key. The writer counted those footer bytes toward the block's common user-key prefix. A seek for the shorter key could then incorrectly skip its newest value or deletion. Thanks to @hanke580 for the reproducer, diagnosis, and writer-side correction in #15439.

The writer now bounds that shared length by the current user-key length. The reader also handles existing affected data blocks and internal-key index blocks by comparing full keys when prefix stripping is unsafe. It keeps the boundary shortcut when the target differs before the guaranteed user prefix: stored prefix length minus the eight-byte footer.

Compatibility and performance

No public API or serialized-format change is required, and existing SSTs can be read correctly without rewriting them. Format 7 and user-key index behavior are preserved.

Reverse internal-key targets that differ only within the final eight prefix bytes still require full-key search. In a same-runner A/B/A microbenchmark (128 keys, 69-byte common prefix, 200,000 seeks per repeat, three repeats), matching-key and early-mismatch timings stayed near baseline. The two tail-mismatch cases cost about 123/465 ns versus 40/21 ns for the repeated baseline. This is a measured legacy-read tradeoff, not a production throughput claim.

Testing

Linux x86-64, GCC 13.3, base 87d4427:

  • Four new regression tests fail on the original source and pass with the patch. The writer test covers 64 footer-boundary configurations; fixed legacy bytes cover data/index seeks, backward iteration, restart boundaries, and empty/long user keys.
  • Six format-7/8 update/delete/new-key API cases pass. Three baseline-created databases read correctly, with all five SST hashes unchanged; deleted-key Seek reaches the end.
  • COERCE_CONTEXT_SWITCH=1: 100 runs of each new test, 400 passes, no failures or timeouts.
  • Normal make check: exit 0; 44,166 GTests pass, and all 1,054 native test/check jobs succeed. Source checks ran sequentially before the suite, following CI's SKIP_FORMAT_BUCK_CHECKS arrangement. The Actions wrapper subsequently failed to parse Make's progress banner; the preserved native logs were revalidated.
  • The status-checked full suite has failures. Same-environment base/candidate controls ran 29 selected cases each, with identical outcome classes (14 aborts/signals, 9 assertion failures, 6 passes). Two format-7 best-efforts recovery cases abort at different sites. This mode is not reported as passing.

Validation record and underlying runs.

Fixes #15439.

AI assistance was used for implementation, test development, and investigation.

Limit the common prefix to the current user key when internal keys share
bytes into the footer. The report in meta#15439 supplied this writer bound.

Recover correct seeks in existing affected data and internal-key index
blocks without rewriting SSTs. Retain boundary shortcuts when the target
differs before the guaranteed user-key prefix; otherwise compare full
keys. Cover footer overlap, legacy blocks, reopen, and compaction.

Fixes meta#15439
Assisted-by: Codex
Copilot AI balanced review requested due to automatic review settings October 30, 2026 11:29
@meta-cla

meta-cla Bot commented Oct 30, 2026

Copy link
Copy Markdown

Hi @xgbtxy!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

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.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

2 participants