()
| 155 | } |
| 156 | |
| 157 | func newBackupMetaValidateCommand() *cobra.Command { |
| 158 | command := &cobra.Command{ |
| 159 | Use: "validate", |
| 160 | Short: "validate key range and rewrite rules of backupmeta", |
| 161 | RunE: func(cmd *cobra.Command, _ []string) error { |
| 162 | ctx, cancel := context.WithCancel(GetDefaultContext()) |
| 163 | defer cancel() |
| 164 | |
| 165 | tableIDOffset, err := cmd.Flags().GetUint64("offset") |
| 166 | if err != nil { |
| 167 | return errors.Trace(err) |
| 168 | } |
| 169 | |
| 170 | var cfg task.Config |
| 171 | if err = cfg.ParseFromFlags(cmd.Flags()); err != nil { |
| 172 | return errors.Trace(err) |
| 173 | } |
| 174 | _, s, backupMeta, err := task.ReadBackupMeta(ctx, metautil.MetaFile, &cfg) |
| 175 | if err != nil { |
| 176 | log.Error("read backupmeta failed", zap.Error(err)) |
| 177 | return errors.Trace(err) |
| 178 | } |
| 179 | reader := metautil.NewMetaReader(backupMeta, s, &cfg.CipherInfo) |
| 180 | dbs, err := metautil.LoadBackupTables(ctx, reader, false) |
| 181 | if err != nil { |
| 182 | log.Error("load tables failed", zap.Error(err)) |
| 183 | return errors.Trace(err) |
| 184 | } |
| 185 | files := make([]*backuppb.File, 0) |
| 186 | tables := make([]*metautil.Table, 0) |
| 187 | for _, db := range dbs { |
| 188 | for _, table := range db.Tables { |
| 189 | for _, fs := range table.FilesOfPhysicals { |
| 190 | files = append(files, fs...) |
| 191 | } |
| 192 | } |
| 193 | tables = append(tables, db.Tables...) |
| 194 | } |
| 195 | // Check if the ranges of files overlapped |
| 196 | rangeTree := rtree.NewRangeTree() |
| 197 | for _, file := range files { |
| 198 | if out := rangeTree.InsertRange(rtree.Range{ |
| 199 | KeyRange: rtree.KeyRange{ |
| 200 | StartKey: file.GetStartKey(), |
| 201 | EndKey: file.GetEndKey(), |
| 202 | }, |
| 203 | }); out != nil { |
| 204 | log.Error( |
| 205 | "file ranges overlapped", |
| 206 | zap.Stringer("out", out), |
| 207 | logutil.File(file), |
| 208 | ) |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | tableIDAllocator := mockid.NewIDAllocator() |
| 213 | // Advance table ID allocator to the offset. |
| 214 | for offset := uint64(0); offset < tableIDOffset; offset++ { |
no test coverage detected