mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-20 22:27:04 +00:00
fix(topology): restore active count after vacuum recovery (#9770)
This commit is contained in:
@@ -788,9 +788,15 @@ func (vl *VolumeLayout) SetVolumeUnavailable(dn *DataNode, vid needle.VolumeId)
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (vl *VolumeLayout) SetVolumeAvailable(dn *DataNode, vid needle.VolumeId, isReadOnly, isFullCapacity bool) bool {
|
||||
func (vl *VolumeLayout) SetVolumeAvailable(dn *DataNode, vid needle.VolumeId, isReadOnly, isFullCapacity bool) (becameWritable bool) {
|
||||
restoreActiveVolumeCount := false
|
||||
vl.accessLock.Lock()
|
||||
defer vl.accessLock.Unlock()
|
||||
defer func() {
|
||||
vl.accessLock.Unlock()
|
||||
if restoreActiveVolumeCount {
|
||||
vl.adjustActiveVolumeCount(vid, +1)
|
||||
}
|
||||
}()
|
||||
|
||||
vInfo, err := dn.GetVolumesById(vid)
|
||||
if err != nil {
|
||||
@@ -804,9 +810,17 @@ func (vl *VolumeLayout) SetVolumeAvailable(dn *DataNode, vid needle.VolumeId, is
|
||||
}
|
||||
|
||||
if vl.enoughCopies(vid) {
|
||||
return vl.setVolumeWritable(vid)
|
||||
becameWritable = vl.setVolumeWritable(vid)
|
||||
if becameWritable {
|
||||
if st := vl.sizeTracking[vid]; st != nil && !st.fullSince.IsZero() {
|
||||
// fullSince marks a prior capacity-full removal that already
|
||||
// decremented activeVolumeCount. Re-adding must pair it once.
|
||||
st.fullSince = time.Time{}
|
||||
restoreActiveVolumeCount = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
return becameWritable
|
||||
}
|
||||
|
||||
func (vl *VolumeLayout) enoughCopies(vid needle.VolumeId) bool {
|
||||
|
||||
@@ -67,3 +67,52 @@ func TestSetVolumeCapacityFullStampsFullSinceAndRecovers(t *testing.T) {
|
||||
t.Fatalf("expected fullSince cleared after recovery")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetVolumeAvailableRestoresActiveCountForCapacityFullVolume(t *testing.T) {
|
||||
layout := `
|
||||
{
|
||||
"dc1":{
|
||||
"rack1":{
|
||||
"server1":{
|
||||
"volumes":[
|
||||
{"id":1, "size":4000, "replication":"000"}
|
||||
],
|
||||
"limit":10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
topo, vl := setupPickTest(t, layout, 10000)
|
||||
|
||||
initialActive := topo.diskUsages.usages[types.HardDriveType].activeVolumeCount
|
||||
if !vl.SetVolumeCapacityFull(1) {
|
||||
t.Fatalf("SetVolumeCapacityFull should report the volume was writable")
|
||||
}
|
||||
vl.AdjustActiveVolumeCountForFull(1)
|
||||
if got := topo.diskUsages.usages[types.HardDriveType].activeVolumeCount; got != initialActive-1 {
|
||||
t.Fatalf("expected activeVolumeCount decremented to %d, got %d", initialActive-1, got)
|
||||
}
|
||||
|
||||
vl.accessLock.RLock()
|
||||
dn := vl.vid2location[1].list[0]
|
||||
vl.accessLock.RUnlock()
|
||||
|
||||
if !vl.SetVolumeAvailable(dn, 1, false, false) {
|
||||
t.Fatalf("SetVolumeAvailable should report the volume became writable")
|
||||
}
|
||||
if got := topo.diskUsages.usages[types.HardDriveType].activeVolumeCount; got != initialActive {
|
||||
t.Fatalf("expected SetVolumeAvailable to restore activeVolumeCount to %d, got %d", initialActive, got)
|
||||
}
|
||||
if !vl.sizeTracking[1].fullSince.IsZero() {
|
||||
t.Fatalf("expected SetVolumeAvailable to clear fullSince after restoring activeVolumeCount")
|
||||
}
|
||||
|
||||
advanceSizeTrackingClock(vl, 1, capacityRecoveryDelay+time.Second)
|
||||
if vl.UpdateVolumeSize(1, 4000, 0) {
|
||||
t.Fatalf("heartbeat recovery should not fire after SetVolumeAvailable already restored the volume")
|
||||
}
|
||||
if got := topo.diskUsages.usages[types.HardDriveType].activeVolumeCount; got != initialActive {
|
||||
t.Fatalf("expected activeVolumeCount to remain %d, got %d", initialActive, got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user