merge: vid-growth-freeze updates

This commit is contained in:
Chris Lu
2026-10-18 21:02:11 -07:00
2 changed files with 32 additions and 3 deletions
+21
View File
@@ -43,6 +43,27 @@ func TestMaxVolumeIdFileRestoresTopologyId(t *testing.T) {
}
}
func TestMaxVolumeIdFileRewritesOnTopologyIdChange(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "max_volume_id")
topo := NewTopology("topo", nil, 0, 5, false)
topo.SetMaxVolumeIdFile(file)
if err := topo.PersistMaxVolumeId(needle.VolumeId(7)); err != nil {
t.Fatalf("persist: %v", err)
}
topo.SetTopologyId("cluster-b")
if err := topo.PersistMaxVolumeId(needle.VolumeId(7)); err != nil {
t.Fatalf("persist same bound with new topology id: %v", err)
}
restarted := NewTopology("topo", nil, 0, 5, false)
restarted.SetMaxVolumeIdFile(file)
if got := restarted.GetTopologyId(); got != "cluster-b" {
t.Fatalf("restored topology id = %q, want cluster-b", got)
}
}
func TestMaxVolumeIdFileMonotonic(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "max_volume_id")
+11 -3
View File
@@ -87,6 +87,7 @@ type Topology struct {
maxVolumeIdFile string
maxVolumeIdFileLock sync.Mutex
lastPersistedMaxVolumeId atomic.Uint32
lastPersistedTopologyId atomic.Value
growthFrozen atomic.Bool
growthFrozenAt atomic.Int64
@@ -1162,6 +1163,7 @@ func (t *Topology) SetMaxVolumeIdFile(file string) {
return
}
t.lastPersistedMaxVolumeId.Store(uint32(cmd.MaxVolumeId))
t.lastPersistedTopologyId.Store(cmd.TopologyId)
t.UpAdjustMaxVolumeId(cmd.MaxVolumeId)
if cmd.TopologyId != "" {
t.SetTopologyId(cmd.TopologyId)
@@ -1175,19 +1177,24 @@ func (t *Topology) SetMaxVolumeIdFile(file string) {
// leader before a raft apply and by both raft implementations on apply and
// recovery, so follower mirrors stay current too.
func (t *Topology) PersistMaxVolumeId(vid needle.VolumeId) error {
if t.lastPersistedMaxVolumeId.Load() >= uint32(vid) {
topoId := t.GetTopologyId()
mirrored := func() bool {
return t.lastPersistedMaxVolumeId.Load() >= uint32(vid) && t.lastPersistedTopologyId.Load() == topoId
}
if mirrored() {
return nil
}
t.maxVolumeIdFileLock.Lock()
defer t.maxVolumeIdFileLock.Unlock()
if t.lastPersistedMaxVolumeId.Load() >= uint32(vid) {
if mirrored() {
return nil
}
if t.maxVolumeIdFile == "" {
t.lastPersistedMaxVolumeId.Store(uint32(vid))
t.lastPersistedTopologyId.Store(topoId)
return nil
}
cmd := NewMaxVolumeIdCommand(vid, t.GetTopologyId())
cmd := NewMaxVolumeIdCommand(vid, topoId)
if t.growthFrozen.Load() {
cmd.GrowthFrozen = new(bool)
*cmd.GrowthFrozen = true
@@ -1219,5 +1226,6 @@ func (t *Topology) PersistMaxVolumeId(vid needle.VolumeId) error {
return err
}
t.lastPersistedMaxVolumeId.Store(uint32(vid))
t.lastPersistedTopologyId.Store(topoId)
return nil
}