Repository navigation
Fix early manifest deletion in CAS GC - #2730
Conversation
Apply the mount floor to candidates without a catalog row. Recheck each candidate's full catalog row after floor reads and before reading bodies. Retain candidates whose namespace appears, disappears, or changes life. Add deterministic regressions for staged publication and catalog races. Verification: 8/9 regressions failed before the fix; 9/9 pass after it. https://gist.github.com/filimonov/1b96ea358804b1c6e22c45380cc65469 https://gist.github.com/k-morozov/13a60ab4424b1b20ba54e4d89b1c0917 Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Cover rowless mount floors, epoch boundaries, per-namespace catalog changes, cursor progress after retention, and catalog request counts. Document the floor and catalog checks before candidate body reads. Verification: unit_tests_dbms built successfully; 53 tests from CASOrphanManifestSweep, CASOrphanSweepRequests and CASSweepDeletionPremise pass. Scoped whitespace checks and documentation anchors pass. https://gist.github.com/filimonov/1b96ea358804b1c6e22c45380cc65469 https://gist.github.com/k-morozov/13a60ab4424b1b20ba54e4d89b1c0917 https://gist.github.com/k-morozov/5c81c35c5ea432c36f4467ece81dc2ce Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Move mount-floor eligibility into `isBuildBelowFloor` and the second catalog cut into `filterCandidatesByCatalog`. Keep cursor progress in `planManifestCursorPage` and preserve skip accounting. Preserve floor caching, request counts and the order of observations. https://gist.github.com/filimonov/1b96ea358804b1c6e22c45380cc65469 https://gist.github.com/k-morozov/13a60ab4424b1b20ba54e4d89b1c0917 Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Use `excludeCandidatesWithChangedCatalogEntries` and `rechecked_catalog` to describe the catalog recheck and its candidate filtering. https://gist.github.com/filimonov/1b96ea358804b1c6e22c45380cc65469 https://gist.github.com/k-morozov/13a60ab4424b1b20ba54e4d89b1c0917 Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Use `build_prefix` for the listed manifest's build identity and name the mount-lease lookup and cache after their actual values. Rename the cached check to `isBuildUnderFloor` and explain its condition at the call site. Keep the `prefixEligible` API and its lease-based predicate unchanged. Related: #2730 https://gist.github.com/filimonov/1b96ea358804b1c6e22c45380cc65469 Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Introduce `BuildFloor` and use `transform(toBuildFloor)` to extract the epoch and active-build boundary from a `MountLease`. Pass this boundary to `buildPrefixEligibleUnderFloor`. Rename the pool and operation helpers consistently, use `build_prefix`, and compare the floor on the left without changing eligibility rules. Update callers and existing tests. Preserve the mount format and request counts. Related: #2730 https://gist.github.com/filimonov/1b96ea358804b1c6e22c45380cc65469 Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
Describe how a writer can commit a ref and advance the floor after the initial catalog read, leaving the old cut without the namespace entry. Related: #2730 https://gist.github.com/filimonov/1b96ea358804b1c6e22c45380cc65469 Signed-off-by: Konstantin Morozov <just.morozov.k@gmail.com>
PR #2730 Audit Review
VerdictNo confirmed defects in reviewed scope. The race the changelog names is closed. A staged manifest is nominated only after the mount floor says its build is finished and a second catalog read still shows the same row, or no row. Confirmed defectsNo confirmed defects in reviewed scope. What the change does
Why the fix holdsA key is nominated only when all three of these are true:
That lines up with the writer order at this head.
A Keys spared by The renamed predicate is the same four outcomes: older epoch, same epoch below the floor, same epoch at or above the floor, and the farewell sentinel. What was checked and found clean
Coverage
Assumptions and limits. Static reading of Operational readinessScope. Background orphan sweep on the GC leader while a writer stages a manifest for a new or recreated namespace. Persona: operator / DBA. Primary flows.
No operator-facing defect in those flows. There is no new setting. A body whose namespace does not resolve to a mount lease stays until a lease exists. A body the second catalog read spares is visited again after the manifest cursor wraps The data-loss race remains on a replica that still runs the old planner and wins GC leadership. Upgrade that replica onto this build. |
PR #2730 CI Verification
VerdictNo failure in scope is caused by this pull request. The diff is the orphan-manifest sweep. Unit tests passed ( The red integration jobs are a named-collection grant, an S3 multipart assert in
How the list was reducedThe CI report has 58 integration failures. The Swarms job is out of scope and is not classified.
|
| Job | What happened |
|---|---|
RegressionTestsRelease / S3Export (part) |
Cancelled during Run s3 suite after about 3.5 hours. s3_export_partition in the same workflow passed |
RegressionTestsRelease / CASS3CacheLightweightDelete (3) |
Cancelled while Run lightweight_delete suite had not finished. The other CAS lightweight-delete lanes passed, including non-cache lane 3 |
What passed that this pull request cares about
CAS regression, including S3-cache lanes that finished: all success. cas itself is 52/52. Iceberg (1) and (2), Parquet, Parquet S3 (minio and aws_s3), OAuth, and S3 export partition passed. Stateless debug is 13637 passed, 0 failed. The two selected stateless shards passed. Unit tests (asan_ubsan) passed.
|
maybe let's backport it to 26.6 later. |
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Fix races in CAS garbage collection that could delete manifests during namespace creation or recreation, causing data loss.
Documentation entry for user-facing changes
...
CI/CD Options
Exclude tests:
Regression jobs to run: