Skip to content

Commit 4916d15

Browse files
authored
cherry-pick-7.5: br: restore checksum shouldn't rely on backup checksum (#56712) (#58225)
1 parent 1c32d6b commit 4916d15

File tree

18 files changed

+158
-79
lines changed

18 files changed

+158
-79
lines changed

br/cmd/br/backup.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ import (
2121

2222
func runBackupCommand(command *cobra.Command, cmdName string) error {
2323
cfg := task.BackupConfig{Config: task.Config{LogProgress: HasLogFile()}}
24-
if err := cfg.ParseFromFlags(command.Flags()); err != nil {
24+
if err := cfg.ParseFromFlags(command.Flags(), false); err != nil {
2525
command.SilenceUsage = false
2626
return errors.Trace(err)
2727
}
28+
overrideDefaultBackupConfigIfNeeded(&cfg, command)
2829

2930
if err := metricsutil.RegisterMetricsForBR(cfg.PD, cfg.KeyspaceName); err != nil {
3031
return errors.Trace(err)
@@ -206,3 +207,10 @@ func newTxnBackupCommand() *cobra.Command {
206207
task.DefineTxnBackupFlags(command)
207208
return command
208209
}
210+
211+
func overrideDefaultBackupConfigIfNeeded(config *task.BackupConfig, cmd *cobra.Command) {
212+
// override only if flag not set by user
213+
if !cmd.Flags().Changed(task.FlagChecksum) {
214+
config.Checksum = false
215+
}
216+
}

br/cmd/br/cmd.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ func timestampLogFileName() string {
7979
return filepath.Join(os.TempDir(), time.Now().Format("br.log.2006-01-02T15.04.05Z0700"))
8080
}
8181

82-
// AddFlags adds flags to the given cmd.
83-
func AddFlags(cmd *cobra.Command) {
82+
// DefineCommonFlags defines the common flags for all BR cmd operation.
83+
func DefineCommonFlags(cmd *cobra.Command) {
8484
cmd.Version = build.Info()
8585
cmd.Flags().BoolP(flagVersion, flagVersionShort, false, "Display version information about BR")
8686
cmd.SetVersionTemplate("{{printf \"%s\" .Version}}\n")
@@ -97,6 +97,8 @@ func AddFlags(cmd *cobra.Command) {
9797
"Set whether to redact sensitive info in log")
9898
cmd.PersistentFlags().String(FlagStatusAddr, "",
9999
"Set the HTTP listening address for the status report service. Set to empty string to disable")
100+
101+
// defines BR task common flags, this is shared by cmd and sql(brie)
100102
task.DefineCommonFlags(cmd.PersistentFlags())
101103

102104
cmd.PersistentFlags().StringP(FlagSlowLogFile, "", "",

br/cmd/br/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func main() {
2020
TraverseChildren: true,
2121
SilenceUsage: true,
2222
}
23-
AddFlags(rootCmd)
23+
DefineCommonFlags(rootCmd)
2424
SetDefaultContext(ctx)
2525
rootCmd.AddCommand(
2626
NewDebugCommand(),

br/cmd/br/restore.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323

2424
func runRestoreCommand(command *cobra.Command, cmdName string) error {
2525
cfg := task.RestoreConfig{Config: task.Config{LogProgress: HasLogFile()}}
26-
if err := cfg.ParseFromFlags(command.Flags()); err != nil {
26+
if err := cfg.ParseFromFlags(command.Flags(), false); err != nil {
2727
command.SilenceUsage = false
2828
return errors.Trace(err)
2929
}

br/pkg/backup/schema.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (ss *Schemas) BackupSchemas(
104104
}
105105

106106
var checksum *checkpoint.ChecksumItem
107-
var exists bool = false
107+
var exists = false
108108
if ss.checkpointChecksum != nil && schema.tableInfo != nil {
109109
checksum, exists = ss.checkpointChecksum[schema.tableInfo.ID]
110110
}
@@ -143,7 +143,7 @@ func (ss *Schemas) BackupSchemas(
143143
zap.Uint64("Crc64Xor", schema.crc64xor),
144144
zap.Uint64("TotalKvs", schema.totalKvs),
145145
zap.Uint64("TotalBytes", schema.totalBytes),
146-
zap.Duration("calculate-take", calculateCost))
146+
zap.Duration("TimeTaken", calculateCost))
147147
}
148148
}
149149
if statsHandle != nil {

br/pkg/metautil/metafile.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,6 @@ type Table struct {
156156
Stats *util.JSONTable
157157
}
158158

159-
// NoChecksum checks whether the table has a calculated checksum.
160-
func (tbl *Table) NoChecksum() bool {
161-
return tbl.Crc64Xor == 0 && tbl.TotalKvs == 0 && tbl.TotalBytes == 0
162-
}
163-
164159
// MetaReader wraps a reader to read both old and new version of backupmeta.
165160
type MetaReader struct {
166161
storage storage.ExternalStorage
@@ -225,14 +220,38 @@ func (reader *MetaReader) readDataFiles(ctx context.Context, output func(*backup
225220
}
226221

227222
// ArchiveSize return the size of Archive data
228-
func (*MetaReader) ArchiveSize(_ context.Context, files []*backuppb.File) uint64 {
223+
func ArchiveSize(files []*backuppb.File) uint64 {
229224
total := uint64(0)
230225
for _, file := range files {
231226
total += file.Size_
232227
}
233228
return total
234229
}
235230

231+
type ChecksumStats struct {
232+
Crc64Xor uint64
233+
TotalKvs uint64
234+
TotalBytes uint64
235+
}
236+
237+
func (stats ChecksumStats) ChecksumExists() bool {
238+
if stats.Crc64Xor == 0 && stats.TotalKvs == 0 && stats.TotalBytes == 0 {
239+
return false
240+
}
241+
return true
242+
}
243+
244+
// CalculateChecksumStatsOnFiles returns the ChecksumStats for the given files
245+
func CalculateChecksumStatsOnFiles(files []*backuppb.File) ChecksumStats {
246+
var stats ChecksumStats
247+
for _, file := range files {
248+
stats.Crc64Xor ^= file.Crc64Xor
249+
stats.TotalKvs += file.TotalKvs
250+
stats.TotalBytes += file.TotalBytes
251+
}
252+
return stats
253+
}
254+
236255
// ReadDDLs reads the ddls from the backupmeta.
237256
// This function is compatible with the old backupmeta.
238257
func (reader *MetaReader) ReadDDLs(ctx context.Context) ([]byte, error) {

br/pkg/restore/client.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,7 +1696,7 @@ func (rc *Client) GoValidateChecksum(
16961696
elapsed := time.Since(start)
16971697
summary.CollectSuccessUnit("table checksum", 1, elapsed)
16981698
}()
1699-
err := rc.execChecksum(c, tbl, kvClient, concurrency)
1699+
err := rc.execAndValidateChecksum(c, tbl, kvClient, concurrency)
17001700
if err != nil {
17011701
return errors.Trace(err)
17021702
}
@@ -1708,7 +1708,7 @@ func (rc *Client) GoValidateChecksum(
17081708
return outCh
17091709
}
17101710

1711-
func (rc *Client) execChecksum(
1711+
func (rc *Client) execAndValidateChecksum(
17121712
ctx context.Context,
17131713
tbl *CreatedTable,
17141714
kvClient kv.Client,
@@ -1719,13 +1719,14 @@ func (rc *Client) execChecksum(
17191719
zap.String("table", tbl.OldTable.Info.Name.O),
17201720
)
17211721

1722-
if tbl.OldTable.NoChecksum() {
1722+
expectedChecksumStats := metautil.CalculateChecksumStatsOnFiles(tbl.OldTable.Files)
1723+
if !expectedChecksumStats.ChecksumExists() {
17231724
logger.Warn("table has no checksum, skipping checksum")
17241725
return nil
17251726
}
17261727

17271728
if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil {
1728-
span1 := span.Tracer().StartSpan("Client.execChecksum", opentracing.ChildOf(span.Context()))
1729+
span1 := span.Tracer().StartSpan("Client.execAndValidateChecksum", opentracing.ChildOf(span.Context()))
17291730
defer span1.Finish()
17301731
ctx = opentracing.ContextWithSpan(ctx, span1)
17311732
}
@@ -1765,21 +1766,24 @@ func (rc *Client) execChecksum(
17651766
}
17661767
}
17671768
}
1768-
table := tbl.OldTable
1769-
if item.Crc64xor != table.Crc64Xor ||
1770-
item.TotalKvs != table.TotalKvs ||
1771-
item.TotalBytes != table.TotalBytes {
1769+
checksumMatch := item.Crc64xor == expectedChecksumStats.Crc64Xor &&
1770+
item.TotalKvs == expectedChecksumStats.TotalKvs &&
1771+
item.TotalBytes == expectedChecksumStats.TotalBytes
1772+
failpoint.Inject("full-restore-validate-checksum", func(_ failpoint.Value) {
1773+
checksumMatch = false
1774+
})
1775+
if !checksumMatch {
17721776
logger.Error("failed in validate checksum",
1773-
zap.Uint64("origin tidb crc64", table.Crc64Xor),
1777+
zap.Uint64("expected tidb crc64", expectedChecksumStats.Crc64Xor),
17741778
zap.Uint64("calculated crc64", item.Crc64xor),
1775-
zap.Uint64("origin tidb total kvs", table.TotalKvs),
1779+
zap.Uint64("expected tidb total kvs", expectedChecksumStats.TotalKvs),
17761780
zap.Uint64("calculated total kvs", item.TotalKvs),
1777-
zap.Uint64("origin tidb total bytes", table.TotalBytes),
1781+
zap.Uint64("expected tidb total bytes", expectedChecksumStats.TotalBytes),
17781782
zap.Uint64("calculated total bytes", item.TotalBytes),
17791783
)
17801784
return errors.Annotate(berrors.ErrRestoreChecksumMismatch, "failed to validate checksum")
17811785
}
1782-
logger.Info("success in validate checksum")
1786+
logger.Info("success in validating checksum")
17831787
return nil
17841788
}
17851789

br/pkg/task/backup.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import (
4242
"github.com/spf13/pflag"
4343
"github.com/tikv/client-go/v2/oracle"
4444
kvutil "github.com/tikv/client-go/v2/util"
45-
"go.uber.org/multierr"
4645
"go.uber.org/zap"
4746
)
4847

@@ -160,7 +159,7 @@ func DefineBackupFlags(flags *pflag.FlagSet) {
160159
}
161160

162161
// ParseFromFlags parses the backup-related flags from the flag set.
163-
func (cfg *BackupConfig) ParseFromFlags(flags *pflag.FlagSet) error {
162+
func (cfg *BackupConfig) ParseFromFlags(flags *pflag.FlagSet, skipCommonConfig bool) error {
164163
timeAgo, err := flags.GetDuration(flagBackupTimeago)
165164
if err != nil {
166165
return errors.Trace(err)
@@ -213,9 +212,13 @@ func (cfg *BackupConfig) ParseFromFlags(flags *pflag.FlagSet) error {
213212
}
214213
cfg.CompressionConfig = *compressionCfg
215214

216-
if err = cfg.Config.ParseFromFlags(flags); err != nil {
217-
return errors.Trace(err)
215+
// parse common flags if needed
216+
if !skipCommonConfig {
217+
if err = cfg.Config.ParseFromFlags(flags); err != nil {
218+
return errors.Trace(err)
219+
}
218220
}
221+
219222
cfg.RemoveSchedulers, err = flags.GetBool(flagRemoveSchedulers)
220223
if err != nil {
221224
return errors.Trace(err)
@@ -790,18 +793,15 @@ func ParseTSString(ts string, tzCheck bool) (uint64, error) {
790793
return oracle.GoTimeToTS(t1), nil
791794
}
792795

793-
func DefaultBackupConfig() BackupConfig {
796+
func DefaultBackupConfig(commonConfig Config) BackupConfig {
794797
fs := pflag.NewFlagSet("dummy", pflag.ContinueOnError)
795-
DefineCommonFlags(fs)
796798
DefineBackupFlags(fs)
797799
cfg := BackupConfig{}
798-
err := multierr.Combine(
799-
cfg.ParseFromFlags(fs),
800-
cfg.Config.ParseFromFlags(fs),
801-
)
800+
err := cfg.ParseFromFlags(fs, true)
802801
if err != nil {
803-
log.Panic("infallible operation failed.", zap.Error(err))
802+
log.Panic("failed to parse backup flags to config", zap.Error(err))
804803
}
804+
cfg.Config = commonConfig
805805
return cfg
806806
}
807807

br/pkg/task/common.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const (
6464
flagRateLimit = "ratelimit"
6565
flagRateLimitUnit = "ratelimit-unit"
6666
flagConcurrency = "concurrency"
67-
flagChecksum = "checksum"
67+
FlagChecksum = "checksum"
6868
flagFilter = "filter"
6969
flagCaseSensitive = "case-sensitive"
7070
flagRemoveTiFlash = "remove-tiflash"
@@ -273,7 +273,7 @@ func DefineCommonFlags(flags *pflag.FlagSet) {
273273
flags.Uint(flagChecksumConcurrency, variable.DefChecksumTableConcurrency, "The concurrency of checksumming in one table")
274274

275275
flags.Uint64(flagRateLimit, unlimited, "The rate limit of the task, MB/s per node")
276-
flags.Bool(flagChecksum, true, "Run checksum at end of task")
276+
flags.Bool(FlagChecksum, true, "Run checksum at end of task")
277277
flags.Bool(flagRemoveTiFlash, true,
278278
"Remove TiFlash replicas before backup or restore, for unsupported versions of TiFlash")
279279

@@ -318,7 +318,7 @@ func DefineCommonFlags(flags *pflag.FlagSet) {
318318

319319
// HiddenFlagsForStream temporary hidden flags that stream cmd not support.
320320
func HiddenFlagsForStream(flags *pflag.FlagSet) {
321-
_ = flags.MarkHidden(flagChecksum)
321+
_ = flags.MarkHidden(FlagChecksum)
322322
_ = flags.MarkHidden(flagChecksumConcurrency)
323323
_ = flags.MarkHidden(flagRateLimit)
324324
_ = flags.MarkHidden(flagRateLimitUnit)
@@ -505,7 +505,7 @@ func (cfg *Config) ParseFromFlags(flags *pflag.FlagSet) error {
505505
return errors.Trace(err)
506506
}
507507

508-
if cfg.Checksum, err = flags.GetBool(flagChecksum); err != nil {
508+
if cfg.Checksum, err = flags.GetBool(FlagChecksum); err != nil {
509509
return errors.Trace(err)
510510
}
511511
if cfg.ChecksumConcurrency, err = flags.GetUint(flagChecksumConcurrency); err != nil {
@@ -618,6 +618,11 @@ func (cfg *Config) ParseFromFlags(flags *pflag.FlagSet) error {
618618
return cfg.normalizePDURLs()
619619
}
620620

621+
// OverrideDefaultForBackup override common config for backup tasks
622+
func (cfg *Config) OverrideDefaultForBackup() {
623+
cfg.Checksum = false
624+
}
625+
621626
// NewMgr creates a new mgr at the given PD address.
622627
func NewMgr(ctx context.Context,
623628
g glue.Glue, pds []string,

br/pkg/task/common_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,10 @@ func expectedDefaultConfig() Config {
232232
}
233233

234234
func expectedDefaultBackupConfig() BackupConfig {
235+
defaultConfig := expectedDefaultConfig()
236+
defaultConfig.Checksum = false
235237
return BackupConfig{
236-
Config: expectedDefaultConfig(),
238+
Config: defaultConfig,
237239
GCTTL: utils.DefaultBRGCSafePointTTL,
238240
CompressionConfig: CompressionConfig{
239241
CompressionType: backup.CompressionType_ZSTD,
@@ -270,13 +272,16 @@ func TestDefault(t *testing.T) {
270272
}
271273

272274
func TestDefaultBackup(t *testing.T) {
273-
def := DefaultBackupConfig()
275+
commonConfig := DefaultConfig()
276+
commonConfig.OverrideDefaultForBackup()
277+
def := DefaultBackupConfig(commonConfig)
274278
defaultConfig := expectedDefaultBackupConfig()
275279
require.Equal(t, defaultConfig, def)
276280
}
277281

278282
func TestDefaultRestore(t *testing.T) {
279-
def := DefaultRestoreConfig()
283+
commonConfig := DefaultConfig()
284+
def := DefaultRestoreConfig(commonConfig)
280285
defaultConfig := expectedDefaultRestoreConfig()
281286
require.Equal(t, defaultConfig, def)
282287
}

0 commit comments

Comments
 (0)