Close follower files before finishing aofshrink

fixes #449
This commit is contained in:
tidwall 2021-06-13 07:53:27 -07:00
parent 4490eba0fc
commit df8d3d7b12
3 changed files with 28 additions and 17 deletions

View File

@ -483,8 +483,16 @@ func (s *Server) cmdAOF(msg *Message) (res resp.Value, err error) {
} }
func (s *Server) liveAOF(pos int64, conn net.Conn, rd *PipelineReader, msg *Message) error { func (s *Server) liveAOF(pos int64, conn net.Conn, rd *PipelineReader, msg *Message) error {
s.mu.RLock()
f, err := os.Open(s.aof.Name())
s.mu.RUnlock()
if err != nil {
return err
}
defer f.Close()
s.mu.Lock() s.mu.Lock()
s.aofconnM[conn] = true s.aofconnM[conn] = f
s.mu.Unlock() s.mu.Unlock()
defer func() { defer func() {
s.mu.Lock() s.mu.Lock()
@ -497,13 +505,6 @@ func (s *Server) liveAOF(pos int64, conn net.Conn, rd *PipelineReader, msg *Mess
return err return err
} }
s.mu.RLock()
f, err := os.Open(s.aof.Name())
s.mu.RUnlock()
if err != nil {
return err
}
defer f.Close()
if _, err := f.Seek(pos, 0); err != nil { if _, err := f.Seek(pos, 0); err != nil {
return err return err
} }
@ -552,11 +553,13 @@ func (s *Server) liveAOF(pos int64, conn net.Conn, rd *PipelineReader, msg *Mess
// The reader needs to be OK with the eof not // The reader needs to be OK with the eof not
for { for {
n, err := f.Read(b) n, err := f.Read(b)
if err != io.EOF && n > 0 { if n > 0 {
if err != nil { if _, err := conn.Write(b[:n]); err != nil {
return err return err
} }
if _, err := conn.Write(b[:n]); err != nil { }
if err != io.EOF {
if err != nil {
return err return err
} }
continue continue

View File

@ -237,6 +237,18 @@ func (server *Server) aofshrink() {
server.mu.Lock() server.mu.Lock()
defer server.mu.Unlock() defer server.mu.Unlock()
// kill all followers connections and close their files. This
// ensures that there is only one opened AOF at a time which is
// what Windows requires in order to perform the Rename function
// below.
for conn, f := range server.aofconnM {
conn.Close()
f.Close()
}
// send a broadcast to all sleeping followers
server.fcond.Broadcast()
// flush the aof buffer // flush the aof buffer
server.flushAOF(false) server.flushAOF(false)
@ -291,10 +303,6 @@ func (server *Server) aofshrink() {
os.Remove(core.AppendFileName + "-bak") // ignore error os.Remove(core.AppendFileName + "-bak") // ignore error
// kill all followers connections
for conn := range server.aofconnM {
conn.Close()
}
return nil return nil
}() }()
}() }()

View File

@ -123,7 +123,7 @@ type Server struct {
hookCross rtree.RTree // hook spatial tree for "cross" geofences hookCross rtree.RTree // hook spatial tree for "cross" geofences
hookTree rtree.RTree // hook spatial tree for all hookTree rtree.RTree // hook spatial tree for all
hooksOut map[string]*Hook // hooks with "outside" detection hooksOut map[string]*Hook // hooks with "outside" detection
aofconnM map[net.Conn]bool aofconnM map[net.Conn]io.Closer
luascripts *lScriptMap luascripts *lScriptMap
luapool *lStatePool luapool *lStatePool
@ -155,7 +155,7 @@ func Serve(host string, port int, dir string, http bool, metricsAddr string) err
lcond: sync.NewCond(&sync.Mutex{}), lcond: sync.NewCond(&sync.Mutex{}),
hooks: make(map[string]*Hook), hooks: make(map[string]*Hook),
hooksOut: make(map[string]*Hook), hooksOut: make(map[string]*Hook),
aofconnM: make(map[net.Conn]bool), aofconnM: make(map[net.Conn]io.Closer),
expires: rhh.New(0), expires: rhh.New(0),
started: time.Now(), started: time.Now(),
conns: make(map[int]*Client), conns: make(map[int]*Client),