mirror of
https://github.com/pgsty/minio.git
synced 2026-11-10 17:45:32 +03:00
fix(decom): move a tiered version whose restored-copy removal is refused
A decommission walk removes a restored copy that is past its restore deadline before it moves the version, as the scanner would. Since0a546c7a7a refused removal made filterLifecycle return the DeleteRestored action: the walk counted the version as decommissioned without moving it and without queuing an expiry, removeMovedVersions then found a source copy with no retained copy and failed the key with PreConditionFailed, the moved versions of the key stayed duplicated in both pools, the bucket stayed queued and the decommission ended Failed; the retry after a restart failed the same way while the refusal held. The walk now moves the version like any other when the removal is refused, as the release before0a546c7a7did: a copy past its deadline reads as remote, so the version moves with its tier metadata and its restore deadline through DecomTieredObject, the remote object stays, the source copy retires with the key once the destination holds it, and the scanner of the destination pool removes the restored copy by that deadline. The rebalance walk never reaches this action for such a version, which it skips as remote; its filterLifecycle now names the same decision so neither walk counts a restored-copy expiry as a deletion it performed. TestDecommissionMovesRestoredCopyPastDeadline refuses the removal on every drive of the set; before this change it failed with complete=false failed=true, pool 0 holding the version and pool 1 nothing. TestRebalanceLeavesRestoredCopyPastDeadline is the control for the rebalance walk. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
@@ -600,6 +600,12 @@ func (z *erasureServerPools) rebalanceBucket(ctx context.Context, bucket string,
|
||||
|
||||
evt := evalActionFromLifecycle(ctx, *lc, lr, rcfg, objInfo)
|
||||
switch {
|
||||
case evt.Action.DeleteRestored():
|
||||
// A restored copy expires by its own deadline, in the pool
|
||||
// that holds the version; a rebalance does not remove it.
|
||||
// Such a version reads as remote and the walk leaves it, as
|
||||
// the decommission walk moves it: neither counts it as deleted.
|
||||
return lifecycle.NoneAction
|
||||
case evt.Action == lifecycle.DeleteAction && versioned:
|
||||
// Expiring the latest version of a versioned bucket only puts
|
||||
// a delete marker on top of it. The version itself survives as
|
||||
|
||||
Reference in New Issue
Block a user