Persist primary/replica copies after validation mismatch

This commit changes `ValidateReplica()` to persist copies of the
primary & replica databases for inspection if a validation mismatch
occurs.
This commit is contained in:
Ben Johnson
2021-01-31 08:47:06 -07:00
parent 3f268b70f8
commit 4e469f8b02
3 changed files with 59 additions and 15 deletions

36
db.go
View File

@@ -1604,7 +1604,9 @@ func restoreWAL(ctx context.Context, r Replica, generation string, index int, db
// This function obtains a read lock so it prevents syncs from occurring until
// the operation is complete. The database will still be usable but it will be
// unable to checkpoint during this time.
func (db *DB) CRC64() (uint64, Pos, error) {
//
// If dst is set, the database file is copied to that location before checksum.
func (db *DB) CRC64(dst string) (uint64, Pos, error) {
db.mu.Lock()
defer db.mu.Unlock()
@@ -1634,7 +1636,16 @@ func (db *DB) CRC64() (uint64, Pos, error) {
}
pos.Offset = 0
chksum, err := checksumFile(db.Path())
// Copy file, if dst specified.
checksumPath := db.Path()
if dst != "" {
if err := copyFile(dst, db.Path()); err != nil {
return 0, Pos{}, err
}
checksumPath = dst
}
chksum, err := checksumFile(checksumPath)
if err != nil {
return 0, pos, err
}
@@ -1770,3 +1781,24 @@ func headerByteOrder(hdr []byte) (binary.ByteOrder, error) {
return nil, fmt.Errorf("invalid wal header magic: %x", magic)
}
}
func copyFile(dst, src string) error {
r, err := os.Open(src)
if err != nil {
return err
}
defer r.Close()
w, err := os.Create(dst)
if err != nil {
return err
}
defer w.Close()
if _, err := io.Copy(w, r); err != nil {
return err
} else if err := w.Sync(); err != nil {
return err
}
return nil
}