-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mvcc: fix TestHashKVWhenCompacting hash mismatch #8333
mvcc: fix TestHashKVWhenCompacting hash mismatch #8333
Conversation
this pr allows HashKV to get compaction Keep without modifying the treeIndex. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing calls Keep() outside of tests; please update hashkv in this patchset if that's why this is being introduced
mvcc/index.go
Outdated
// Keep finds all revisions to be kept for a Compaction at the given rev. | ||
func (ti *treeIndex) Keep(rev int64) map[revision]struct{} { | ||
available := make(map[revision]struct{}) | ||
ti.Lock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why isn't this RLock
?
mvcc/key_index.go
Outdated
// remove any tombstone | ||
if len(g.revs) == 1 && i != len(ki.generations)-1 { | ||
if len(g.revs)-1 == n && i != len(ki.generations)-1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swapping the order of the if's doesn't look like it preserves the meaning; if n > 0
then delete(available, g.revs[0])
is not the same as the current code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, the code should be delete(available, g.revs[n])
instead of delete(available, g.revs[0])
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why wasn't this caught by unit tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unit tests calls Compact before Keep where Compaction on tombstone clears out the generation. Then the subsequent Keep on the same tombstone rev will not even hit if len(g.revs)-1 == n && i != len(ki.generations)-1 {
since if !g.isEmpty() {
will be empty.
e.g
// Init Tree.
// key: "foo"
// rev: 16
// generations:
// {empty}
// {{14, 0}[1], {14, 1}[2], {16, 0}(t)[3]}
// {{8, 0}[1], {10, 0}[2], {12, 0}(t)[3]}
// {{2, 0}[1], {4, 0}[2], {6, 0}(t)[3]}
// Call Compact(12) keep = {}
// generations:
// {empty}
// {{14, 0}[1], {14, 1}[2], {16, 0}(t)[3]}
// Call Keep(12) keep = {} since there is no generation that contains rev 12.
I'll make unit test more strict.
mvcc/key_index.go
Outdated
ki.doCompact(atRev, available, false) | ||
} | ||
|
||
func (ki *keyIndex) doCompact(atRev int64, available map[revision]struct{}, doModify bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not good practice to have boolean arguments; possibly have
func (ki *keyIndex) doCompact(atRev int64, available map[revision]struct{}) (genIdx int, revIndex int)
and handle the modification after calling doCompact
@@ -767,6 +767,10 @@ func (i *fakeIndex) Compact(rev int64) map[revision]struct{} { | |||
i.Recorder.Record(testutil.Action{Name: "compact", Params: []interface{}{rev}}) | |||
return <-i.indexCompactRespc | |||
} | |||
func (i *fakeIndex) Keep(rev int64) map[revision]struct{} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be in the same commit as the test update
e0592ea
to
9eaa470
Compare
} | ||
keep := s.keep | ||
s.keepMu.Unlock() | ||
keep := s.kvindex.Keep(rev) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only need to acquire s.mu.RLock
instead of s.mu.Lock
now?
9eaa470
to
c7817cd
Compare
Keep finds all revisions to be kept for a Compaction at the given rev.
c7817cd
to
f0f886b
Compare
all fixed. PTAL. |
f0f886b
to
65b6ce5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
mvcc/key_index_test.go
Outdated
} | ||
|
||
func cloneGeneration(g *generation) *generation { | ||
var tmp []revision |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use go built-ins:
tmp := make([]revision, len(g.revs))
copy(tmp, g.revs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If g.revs
is nil, the above code will create a non nil tmp which causes comparison failures.
--- FAIL: TestKeyIndexCompactAndKeep (0.00s)
key_index_test.go:451: #0: ki = g: created[{2 0}] ver[3], revs []mvcc.revision{mvcc.revision{main:2, sub:0}, mvcc.revision{main:4, sub:0}, mvcc.revision{main:6, sub:0}}
g: created[{8 0}] ver[3], revs []mvcc.revision{mvcc.revision{main:8, sub:0}, mvcc.revision{main:10, sub:0}, mvcc.revision{main:12, sub:0}}
g: created[{14 0}] ver[3], revs []mvcc.revision{mvcc.revision{main:14, sub:0}, mvcc.revision{main:14, sub:1}, mvcc.revision{main:16, sub:0}}
g: created[{0 0}] ver[0], revs []mvcc.revision(nil)
, want g: created[{2 0}] ver[3], revs []mvcc.revision{mvcc.revision{main:2, sub:0}, mvcc.revision{main:4, sub:0}, mvcc.revision{main:6, sub:0}}
g: created[{8 0}] ver[3], revs []mvcc.revision{mvcc.revision{main:8, sub:0}, mvcc.revision{main:10, sub:0}, mvcc.revision{main:12, sub:0}}
g: created[{14 0}] ver[3], revs []mvcc.revision{mvcc.revision{main:14, sub:0}, mvcc.revision{main:14, sub:1}, mvcc.revision{main:16, sub:0}}
g: created[{0 0}] ver[0], revs []mvcc.revision{}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK:
if len(g.revs) == nil {
// preserve nils
return nil
}
tmp := make([]revision, len(g.revs))
copy(tmp, g.revs)
return tmp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the return type is *generation
I have the following
func cloneGeneration(g *generation) *generation {
if g.revs == nil {
return &generation{g.ver, g.created, nil}
}
tmp := make([]revision, len(g.revs))
copy(tmp, g.revs)
return &generation{g.ver, g.created, tmp}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok..
65b6ce5
to
bd321b8
Compare
bd321b8
to
df5a3d1
Compare
via https://jenkins-etcd-public.prod.coreos.systems/job/etcd-ci-ppc64/1743/console 2017-08-01 03:15:30.669672 I | etcdserver/api/v3rpc: get error from resetTransport context canceled, transportMonitor returning
2017-08-01 03:15:30.669691 I | etcdserver/api/v3rpc: grpc: addrConn.transportMonitor exits due to: context canceled
Too many goroutines running after all test(s).
1 instances of:
google.golang.org/grpc.(*ClientConn).lbWatcher(...)
/var/jenkins_home/workspace/etcd-ci-ppc64/gopath/src/google.golang.org/grpc/clientconn.go:499 +0x78
created by google.golang.org/grpc.DialContext.func3
/var/jenkins_home/workspace/etcd-ci-ppc64/gopath/src/google.golang.org/grpc/clientconn.go:409 +0x194
1 instances of:
google.golang.org/grpc.(*addrConn).resetTransport(...)
/var/jenkins_home/workspace/etcd-ci-ppc64/gopath/src/google.golang.org/grpc/clientconn.go:903 +0x754
google.golang.org/grpc.(*addrConn).transportMonitor(...)
/var/jenkins_home/workspace/etcd-ci-ppc64/gopath/src/google.golang.org/grpc/clientconn.go:999 +0x460
google.golang.org/grpc.(*ClientConn).resetAddrConn.func1(...)
/var/jenkins_home/workspace/etcd-ci-ppc64/gopath/src/google.golang.org/grpc/clientconn.go:640 +0x1bc
created by google.golang.org/grpc.(*ClientConn).resetAddrConn
/var/jenkins_home/workspace/etcd-ci-ppc64/gopath/src/google.golang.org/grpc/clientconn.go:641 +0x5dc
exit status 1
FAIL github.com/coreos/etcd/clientv3/integration 230.527s Leaky test. I don't think it is related to this pr. |
that's a grpc leak, fine to ignore |
proxy-ci fails via #6934. |
fixes #8311