If old copies exist in the preferred positions, and a new copy is
written to a worse position, keep the old copies and wait for the new
copy to become eligible for trash.
Previously, an old copy would be deleted. This would bring replication
down to the desired level in the short term, but would also cause
extra pulling/copying in the future to restore the optimal copy, and
introduce extra probes for all clients in the meantime.
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>
slots = append(slots, slot{
mnt: mnt,
repl: repl,
- want: repl != nil && (mnt.ReadOnly || repl.Mtime >= bal.MinMtime),
+ want: repl != nil && mnt.ReadOnly,
})
}
}
// TODO: request a Touch if Mtime is duplicated.
var change int
switch {
- case !underreplicated && slot.repl != nil && !slot.want && !unsafeToDelete[slot.repl.Mtime]:
+ case !underreplicated && !slot.want && slot.repl != nil && slot.repl.Mtime < bal.MinMtime && !unsafeToDelete[slot.repl.Mtime]:
slot.mnt.KeepService.AddTrash(Trash{
SizedDigest: blkid,
Mtime: slot.repl.Mtime,
bal.try(c, tester{
desired: map[string]int{"default": 2},
current: slots{0, 1, 2},
- timestamps: []int64{oldTime, newTime, newTime + 1}})
+ timestamps: []int64{oldTime, newTime, newTime + 1},
+ expectResult: balanceResult{
+ have: 3,
+ want: 2,
+ classState: map[string]balancedBlockState{"default": {
+ desired: 2,
+ surplus: 1,
+ unachievable: false}}}})
// The best replicas are too new to delete, but the excess
// replica is old enough.
bal.try(c, tester{