diff --git a/db.go b/db.go index 2fcdbef003..2655bd1992 100644 --- a/db.go +++ b/db.go @@ -220,7 +220,7 @@ func Open(dir string, l log.Logger, r prometheus.Registerer, opts *Options) (db if err := repairBadIndexVersion(l, dir); err != nil { return nil, err } - // Migrate old WAL. + // Migrate old WAL if one exists. if err := MigrateWAL(l, filepath.Join(dir, "wal")); err != nil { return nil, errors.Wrap(err, "migrate WAL") } diff --git a/wal.go b/wal.go index bc48e48ea2..f44dbf0ad8 100644 --- a/wal.go +++ b/wal.go @@ -1212,38 +1212,44 @@ func (r *walReader) decodeDeletes(flag byte, b []byte, res *[]Stone) error { return nil } -// MigrateWAL rewrites the deprecated write ahead log into the new format. -func MigrateWAL(logger log.Logger, dir string) (err error) { - if logger == nil { - logger = log.NewNopLogger() - } +func deprecatedWALExists(logger log.Logger, dir string) (bool, error) { // Detect whether we still have the old WAL. fns, err := sequenceFiles(dir) if err != nil && !os.IsNotExist(err) { - return errors.Wrap(err, "list sequence files") + return false, errors.Wrap(err, "list sequence files") } if len(fns) == 0 { - return nil // No WAL at all yet. + return false, nil // No WAL at all yet. } // Check header of first segment to see whether we are still dealing with an // old WAL. f, err := os.Open(fns[0]) if err != nil { - return errors.Wrap(err, "check first existing segment") + return false, errors.Wrap(err, "check first existing segment") } defer f.Close() var hdr [4]byte if _, err := f.Read(hdr[:]); err != nil && err != io.EOF { - return errors.Wrap(err, "read header from first segment") + return false, errors.Wrap(err, "read header from first segment") } // If we cannot read the magic header for segments of the old WAL, abort. // Either it's migrated already or there's a corruption issue with which // we cannot deal here anyway. Subsequent attempts to open the WAL will error in that case. if binary.BigEndian.Uint32(hdr[:]) != WALMagic { - return nil + return false, nil } + return true, nil +} +// MigrateWAL rewrites the deprecated write ahead log into the new format. +func MigrateWAL(logger log.Logger, dir string) (err error) { + if logger == nil { + logger = log.NewNopLogger() + } + if exists, err := deprecatedWALExists(logger, dir); err != nil || !exists { + return err + } level.Info(logger).Log("msg", "migrating WAL format") tmpdir := dir + ".tmp"