mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-31 21:31:24 +00:00
* heartbeat: name departed volumes in delta heartbeats * master: release the lookup index with a deleted collection * master: keep a fresh grow safe from the report that raced it * volume: name the volumes a deleted collection took with it Deleting a collection left the master to work out what went by omission from the next full volume list, which it no longer gets: heartbeats carry the whole list only when the master asks for it. The volumes a bucket's churn creates and destroys between two of those requests are never named in either direction, so the master keeps counting their slots as occupied and a cluster that creates and drops collections quickly runs its free-slot accounting dry -- assigns fail with no free volumes left while the disk holds a handful of volumes. The destroy path already knows exactly which volumes it removed, so send them down the same channel every other deletion uses. * rust: name the volumes a deleted collection took with it Mirrors the Go volume server. The notify path derives its deltas by diffing snapshots, so a collection delete that does not wake it is invisible until the master next asks for the whole list.
47 lines
1.5 KiB
Go
47 lines
1.5 KiB
Go
package storage
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/super_block"
|
|
)
|
|
|
|
func mountCollectionVolume(t *testing.T, loc *DiskLocation, vid needle.VolumeId, collection string) {
|
|
t.Helper()
|
|
v, err := NewVolume(loc.Directory, loc.IdxDirectory, collection, vid, NeedleMapInMemory,
|
|
&super_block.ReplicaPlacement{}, &needle.TTL{}, 0, needle.GetCurrentVersion(), 0, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
loc.SetVolume(vid, v)
|
|
}
|
|
|
|
// A collection deleted between two heartbeats is the deletion no report would
|
|
// ever name: its volumes can be grown and destroyed without a single list
|
|
// mentioning them, so nothing but this would tell the master their slots came
|
|
// free.
|
|
func TestDeleteCollectionNamesTheVolumesItDestroyed(t *testing.T) {
|
|
store := newTestStore(t, 1)
|
|
mountCollectionVolume(t, store.Locations[0], 1, "books")
|
|
mountCollectionVolume(t, store.Locations[0], 2, "books")
|
|
mountCollectionVolume(t, store.Locations[0], 3, "movies")
|
|
|
|
if err := store.DeleteCollection("books"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
named := make(map[uint32]string)
|
|
for len(store.DeletedVolumesChan) > 0 {
|
|
m := <-store.DeletedVolumesChan
|
|
named[m.Id] = m.Collection
|
|
}
|
|
if len(named) != 2 || named[1] != "books" || named[2] != "books" {
|
|
t.Fatalf("delete named %v, want volumes 1 and 2 of books", named)
|
|
}
|
|
|
|
if _, found := store.Locations[0].FindVolume(3); !found {
|
|
t.Error("another collection's volume was destroyed")
|
|
}
|
|
}
|