Files
rustfs/crates/utils
唐小鸭 899f81f3ad fix(replication): resolve drifted replicas via a target version ledger (#7368)
* fix(replication): resolve drifted replicas via a target version ledger

A replication target that mints its own version ids (Wasabi, AWS S3)
never answers to the source uuid, so every version-addressed mutation
after the initial PUT failed forever: permanent version deletes answered
NoSuchVersion every heal cycle, and tag / retention / legal-hold updates
re-PUT the object, minting one more target version per update
(rustfs/backlog#2340).

Record the id the target assigned as a per-target ledger on the source
version (replication-target-version-<arn>, written through the existing
status writeback) and resolve every later mutation through it: version
deletes DELETE the ledger id, metadata updates go through the
metadata-only Object Lock and tagging APIs. Replicas written before the
ledger existed are located by exact key and ETag, minus the candidates
other generations of the key already claim through their own ledgers; an
ambiguous remainder is refused with a backoff instead of guessed, since a
wrong pick would destroy a live generation. A fresh write never consults
content identity. NoSuchVersion on a version-addressed DELETE counts as
purged.

The fake target gains the Wasabi shape (404 NoSuchVersion on an unknown
id, per-version Object Lock APIs) and the matrix covers the three
mutation classes plus the same-bytes generation case.

* fix(scanner): drop the unused Digest import

Same one-line change as rustfs/rustfs#7366 (main is red with it under -D warnings); carried here so the stacked PRs' merge commits compile until that fix lands.

* fix(admin): probe replication-check mutations by the assigned version id (#7373)

On a target that mints its own version ids the DeleteMarker and
VersionDelete phases of ?replication-check were skipped: they addressed
the source id, which such a target never had. The replication worker now
addresses the id the target assigned (the target-version ledger), and
the probe already holds that id from its own PUT, so run both phases
against it. VersionFidelity keeps failing with the mismatch code and the
target stays FAILED; the phases report whether ledger-addressed purges
work against this endpoint (rustfs/backlog#2340).

* fix(replication): abandon purges to targets the bucket no longer names (#7377)

* fix(admin): probe replication-check mutations by the assigned version id

On a target that mints its own version ids the DeleteMarker and
VersionDelete phases of ?replication-check were skipped: they addressed
the source id, which such a target never had. The replication worker now
addresses the id the target assigned (the target-version ledger), and
the probe already holds that id from its own PUT, so run both phases
against it. VersionFidelity keeps failing with the mismatch code and the
target stays FAILED; the phases report whether ledger-addressed purges
work against this endpoint (rustfs/backlog#2340).

* fix(replication): abandon purges to targets the bucket no longer names

A permanent version delete whose replication keeps failing stays in
xl.meta as a PENDING purge, hidden from listings, until every target
confirms it. Once the operator removes the replication configuration or
the rule naming that target nothing ever confirms it: the heal path
derived its delete decision from the configuration (the decision string
is not persisted) and skipped the version forever, so DeleteBucket
answered BucketNotEmpty for a residue the client could neither list nor
remove (rustfs/backlog#2340).

Owe a version purge to the targets its purge state names, let the heal
path through without a configuration, and have the delete worker settle
a target the configuration no longer names as abandoned: the purge is
reported complete locally through the normal writeback, the replica on
the former target is left alone, and the event
replication_purge_abandoned plus a counter are the record.

* fix(admin): send replication-check marker creation without a version id

Running the DeleteMarker / VersionDelete phases on a target that mints
its own version ids exposed two probe-shape bugs on real Wasabi:

- the DeleteMarker phase put the assigned version id on its DELETE. A
  RustFS peer reads the source-deletemarker header and creates a marker,
  but a generic S3 target executes it as a permanent delete of the probe
  version, so VersionDelete then answered NoSuchVersion. Use the same wire
  shape as live delete replication: no versionId on a marker creation.
- cleanup treated NoSuchVersion on the version the VersionDelete phase had
  already removed as a failure (RustFS/MinIO answer 204 there).

Also gate the no-configuration heal pass-through for pending purges on a
purge state that actually names targets, so a purge without a recorded
target keeps the ordinary skip (scanner unit test), and merge origin/main
(#7365 settles the pool-metadata probe test that failed in CI).

---------

Co-authored-by: houseme <housemecn@gmail.com>
2026-09-07 11:23:32 +00:00
..
2025-12-08 11:23:24 +08:00

RustFS

RustFS Utils - Utility Functions

Essential utility functions and common tools for RustFS distributed object storage

CI 📖 Documentation · 🐛 Bug Reports · 💬 Discussions


📖 Overview

RustFS Utils provides essential utility functions and common tools for the RustFS distributed object storage system. For the complete RustFS experience, please visit the main RustFS repository.

Features

  • Cross-platform system operations and monitoring
  • File system utilities with atomic operations
  • Multi-algorithm compression and encoding support
  • Cryptographic utilities and secure key generation
  • Network utilities and protocol helpers
  • Certificate handling and validation tools

📚 Documentation

For comprehensive documentation, examples, and usage guides, please visit the main RustFS repository.

📄 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.