break MigrateWAL into two functions, detection and migration (#371)

Signed-off-by: Callum Styan <callumstyan@gmail.com>
This commit is contained in:
Callum Styan 2018-09-17 09:30:56 -07:00 committed by Krasi Georgiev
parent 1b651ea7d4
commit 722f0ab920
2 changed files with 17 additions and 11 deletions

2
db.go
View file

@ -220,7 +220,7 @@ func Open(dir string, l log.Logger, r prometheus.Registerer, opts *Options) (db
if err := repairBadIndexVersion(l, dir); err != nil { if err := repairBadIndexVersion(l, dir); err != nil {
return nil, err return nil, err
} }
// Migrate old WAL. // Migrate old WAL if one exists.
if err := MigrateWAL(l, filepath.Join(dir, "wal")); err != nil { if err := MigrateWAL(l, filepath.Join(dir, "wal")); err != nil {
return nil, errors.Wrap(err, "migrate WAL") return nil, errors.Wrap(err, "migrate WAL")
} }

26
wal.go
View file

@ -1212,38 +1212,44 @@ func (r *walReader) decodeDeletes(flag byte, b []byte, res *[]Stone) error {
return nil return nil
} }
// MigrateWAL rewrites the deprecated write ahead log into the new format. func deprecatedWALExists(logger log.Logger, dir string) (bool, error) {
func MigrateWAL(logger log.Logger, dir string) (err error) {
if logger == nil {
logger = log.NewNopLogger()
}
// Detect whether we still have the old WAL. // Detect whether we still have the old WAL.
fns, err := sequenceFiles(dir) fns, err := sequenceFiles(dir)
if err != nil && !os.IsNotExist(err) { 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 { 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 // Check header of first segment to see whether we are still dealing with an
// old WAL. // old WAL.
f, err := os.Open(fns[0]) f, err := os.Open(fns[0])
if err != nil { if err != nil {
return errors.Wrap(err, "check first existing segment") return false, errors.Wrap(err, "check first existing segment")
} }
defer f.Close() defer f.Close()
var hdr [4]byte var hdr [4]byte
if _, err := f.Read(hdr[:]); err != nil && err != io.EOF { 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. // 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 // 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. // we cannot deal here anyway. Subsequent attempts to open the WAL will error in that case.
if binary.BigEndian.Uint32(hdr[:]) != WALMagic { 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") level.Info(logger).Log("msg", "migrating WAL format")
tmpdir := dir + ".tmp" tmpdir := dir + ".tmp"