github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/checksum/validate.go (about) 1 // Copyright 2021 PingCAP, Inc. Licensed under Apache-2.0. 2 3 package checksum 4 5 import ( 6 "context" 7 "time" 8 9 "github.com/pingcap/errors" 10 backuppb "github.com/pingcap/kvproto/pkg/backup" 11 "github.com/pingcap/log" 12 "go.uber.org/zap" 13 14 berrors "github.com/pingcap/br/pkg/errors" 15 "github.com/pingcap/br/pkg/metautil" 16 "github.com/pingcap/br/pkg/storage" 17 "github.com/pingcap/br/pkg/summary" 18 ) 19 20 // FastChecksum checks whether the "local" checksum matches the checksum from TiKV. 21 func FastChecksum( 22 ctx context.Context, backupMeta *backuppb.BackupMeta, storage storage.ExternalStorage, 23 ) error { 24 start := time.Now() 25 defer func() { 26 elapsed := time.Since(start) 27 summary.CollectDuration("backup fast checksum", elapsed) 28 }() 29 30 ch := make(chan *metautil.Table) 31 errCh := make(chan error) 32 go func() { 33 reader := metautil.NewMetaReader(backupMeta, storage) 34 if err := reader.ReadSchemasFiles(ctx, ch); err != nil { 35 errCh <- errors.Trace(err) 36 } 37 close(ch) 38 }() 39 40 for { 41 var tbl *metautil.Table 42 var ok bool 43 select { 44 case <-ctx.Done(): 45 return errors.Trace(ctx.Err()) 46 case tbl, ok = <-ch: 47 if !ok { 48 close(errCh) 49 return nil 50 } 51 } 52 checksum := uint64(0) 53 totalKvs := uint64(0) 54 totalBytes := uint64(0) 55 for _, file := range tbl.Files { 56 checksum ^= file.Crc64Xor 57 totalKvs += file.TotalKvs 58 totalBytes += file.TotalBytes 59 } 60 61 if checksum != tbl.Crc64Xor || 62 totalBytes != tbl.TotalBytes || 63 totalKvs != tbl.TotalKvs { 64 log.Error("checksum mismatch", 65 zap.Stringer("db", tbl.DB.Name), 66 zap.Stringer("table", tbl.Info.Name), 67 zap.Uint64("origin tidb crc64", tbl.Crc64Xor), 68 zap.Uint64("calculated crc64", checksum), 69 zap.Uint64("origin tidb total kvs", tbl.TotalKvs), 70 zap.Uint64("calculated total kvs", totalKvs), 71 zap.Uint64("origin tidb total bytes", tbl.TotalBytes), 72 zap.Uint64("calculated total bytes", totalBytes)) 73 // TODO enhance error 74 return errors.Trace(berrors.ErrBackupChecksumMismatch) 75 } 76 log.Info("checksum success", 77 zap.Stringer("db", tbl.DB.Name), zap.Stringer("table", tbl.Info.Name)) 78 } 79 }