mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
docs(tier-ilm): note local-first invariant for expire/GET race fix (#4651)
This commit is contained in:
@@ -73,16 +73,17 @@ If both `x-rustfs-internal-transitioned-versionID` and
|
||||
`x-minio-internal-transitioned-versionID` are the **empty string**, the object
|
||||
was transitioned to a non-versioned tier bucket and no versionId must be sent.
|
||||
|
||||
## Known open issue: expire/GET race
|
||||
|
||||
`expire_transitioned_object` deletes the remote tier version **before**
|
||||
deleting local metadata. A concurrent GET between those two steps reads a
|
||||
valid stored version_id whose remote version is already gone →
|
||||
`NoSuchVersion`. The proper fix is to delete local metadata first (making the
|
||||
object unreachable), then the remote tier version.
|
||||
|
||||
## Historical fixes (for context, already merged)
|
||||
|
||||
- Expire/GET race (`NoSuchVersion` during expiry of a tiered object):
|
||||
`expire_transitioned_object` used to delete the remote tier version
|
||||
**before** local metadata, so a concurrent GET between the two steps read a
|
||||
stored version_id whose remote version was already gone. Fixed in `#3491`:
|
||||
local metadata is deleted **first** (making the object unreachable), and
|
||||
remote-tier cleanup is driven by persisted free-version recovery
|
||||
(`crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs`).
|
||||
**Invariant — keep local-first ordering**: never remove a remote tier
|
||||
version while live local metadata still points at it.
|
||||
- Nil-UUID versionId sent to tier (`NoSuchVersion`): reading code used
|
||||
`Uuid::from_slice(..).unwrap_or_default()`, converting an empty metadata
|
||||
value into `Uuid::nil()`. Fixed by the `and_then`/`filter` pattern above.
|
||||
|
||||
Reference in New Issue
Block a user