diff --git a/wal/wal.go b/wal/wal.go index ff8e79649..ecc809446 100644 --- a/wal/wal.go +++ b/wal/wal.go @@ -336,6 +336,7 @@ func (w *WAL) sync() error { // lock 1,2 but keep 3. ReleaseLockTo(5) will release 1,2,3 but keep 4. func (w *WAL) ReleaseLockTo(index uint64) error { var smaller int + found := false for i, l := range w.locks { _, lockIndex, err := parseWalName(path.Base(l.Name())) @@ -344,10 +345,17 @@ func (w *WAL) ReleaseLockTo(index uint64) error { } if lockIndex >= index { smaller = i - 1 + found = true break } } + // if no lock index is greater than the release index, we can + // release lock upto the last one(excluding). + if !found && len(w.locks) != 0 { + smaller = len(w.locks) - 1 + } + if smaller <= 0 { return nil } diff --git a/wal/wal_test.go b/wal/wal_test.go index 33b727573..9545feb61 100644 --- a/wal/wal_test.go +++ b/wal/wal_test.go @@ -20,7 +20,6 @@ import ( "os" "path" "reflect" - "testing" "github.com/coreos/etcd/pkg/pbutil" "github.com/coreos/etcd/raft/raftpb" @@ -504,4 +503,21 @@ func TestReleaseLockTo(t *testing.T) { t.Errorf("#%d: lockindex = %d, want %d", i, lockIndex, uint64(i+4)) } } + + // release the lock to 15 + unlockIndex = uint64(15) + w.ReleaseLockTo(unlockIndex) + + // expected remaining is 10 + if len(w.locks) != 1 { + t.Errorf("len(w.locks) = %d, want %d", len(w.locks), 1) + } + _, lockIndex, err := parseWalName(path.Base(w.locks[0].Name())) + if err != nil { + t.Fatal(err) + } + + if lockIndex != uint64(10) { + t.Errorf("lockindex = %d, want %d", lockIndex, 10) + } }