Truncate trailing zeros from AOF at startup

This commit addresses issue #230, where an AOF file will sometimes
not load due to the file being padded with trailing zeros. It's
uncertain what is causing this corruption, but it appears to be
coming from outside of the tile38-server process. I suspect it's
due to some block store layer in Kubernetes/Docker cloud
environments.

This fix allows for Tile38 to start up by discovering the trailing
zeros while loading the AOF and safely truncating the file as to
not include the zeros in the future.
This commit is contained in:
tidwall 2020-10-07 09:52:32 -07:00
parent 3f87be18b4
commit 93e3a067b7
1 changed files with 24 additions and 1 deletions

View File

@ -32,7 +32,7 @@ func (err errAOFHook) Error() string {
var errInvalidAOF = errors.New("invalid aof file")
func (s *Server) loadAOF() error {
func (s *Server) loadAOF() (err error) {
fi, err := s.aof.Stat()
if err != nil {
return err
@ -58,6 +58,7 @@ func (s *Server) loadAOF() error {
var buf []byte
var args [][]byte
var packet [0xFFFF]byte
var zeros int
for {
n, err := s.aof.Read(packet[:])
if err != nil {
@ -65,6 +66,18 @@ func (s *Server) loadAOF() error {
if len(buf) > 0 {
return io.ErrUnexpectedEOF
}
if zeros > 0 {
// Trailing zeros in AOF. Truncate the file so it's sane.
// See issue #230 for more information. Force a warning.
log.Infof("Truncating %d zeros from AOF (issue #230)", zeros)
s.aofsz -= zeros
if err := s.aof.Truncate(int64(s.aofsz)); err != nil {
return err
}
if _, err := s.aof.Seek(int64(s.aofsz), 0); err != nil {
return err
}
}
return nil
}
return err
@ -76,6 +89,16 @@ func (s *Server) loadAOF() error {
}
var complete bool
for {
if len(data) > 0 {
if data[0] == 0 {
zeros++
data = data[1:]
continue
}
if zeros > 0 {
return errors.New("Zeros found in AOF file (issue #230)")
}
}
complete, args, _, data, err = redcon.ReadNextCommand(data, args[:0])
if err != nil {
return err