diff --git a/server/mvcc/watchable_store.go b/server/mvcc/watchable_store.go index 3c7edb33371..0e5be8ecb26 100644 --- a/server/mvcc/watchable_store.go +++ b/server/mvcc/watchable_store.go @@ -355,8 +355,11 @@ func (s *watchableStore) syncWatchers() int { tx := s.store.b.ReadTx() tx.RLock() revs, vs := tx.UnsafeRange(buckets.Key, minBytes, maxBytes, 0) - tx.RUnlock() evs := kvsToEvents(s.store.lg, wg, revs, vs) + // Must unlock after kvsToEvents, because vs (come from boltdb memory) is not deep copy. + // We can only unlock after Unmarshal, which will do deep copy. + // Otherwise we will trigger SIGSEGV during boltdb re-mmap. + tx.RUnlock() var victims watcherBatch wb := newWatcherBatch(wg, evs)