github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/lightning/checkpoints/checkpoints_file_test.go (about) 1 package checkpoints_test 2 3 import ( 4 "context" 5 "path/filepath" 6 "sort" 7 "testing" 8 9 . "github.com/pingcap/check" 10 "github.com/pingcap/errors" 11 12 "github.com/pingcap/br/pkg/lightning/checkpoints" 13 "github.com/pingcap/br/pkg/lightning/config" 14 "github.com/pingcap/br/pkg/lightning/mydump" 15 "github.com/pingcap/br/pkg/lightning/verification" 16 ) 17 18 func Test(t *testing.T) { 19 TestingT(t) 20 } 21 22 var _ = Suite(&cpFileSuite{}) 23 24 type cpFileSuite struct { 25 cpdb *checkpoints.FileCheckpointsDB 26 } 27 28 func newTestConfig() *config.Config { 29 cfg := config.NewConfig() 30 cfg.Mydumper.SourceDir = "/data" 31 cfg.TaskID = 123 32 cfg.TiDB.Port = 4000 33 cfg.TiDB.PdAddr = "127.0.0.1:2379" 34 cfg.TikvImporter.Backend = config.BackendLocal 35 cfg.TikvImporter.Addr = "127.0.0.1:8287" 36 cfg.TikvImporter.SortedKVDir = "/tmp/sorted-kv" 37 return cfg 38 } 39 40 func (s *cpFileSuite) SetUpTest(c *C) { 41 dir := c.MkDir() 42 s.cpdb = checkpoints.NewFileCheckpointsDB(filepath.Join(dir, "cp.pb")) 43 44 ctx := context.Background() 45 cpdb := s.cpdb 46 47 // 2. initialize with checkpoint data. 48 cfg := newTestConfig() 49 err := cpdb.Initialize(ctx, cfg, map[string]*checkpoints.TidbDBInfo{ 50 "db1": { 51 Name: "db1", 52 Tables: map[string]*checkpoints.TidbTableInfo{ 53 "t1": {Name: "t1"}, 54 "t2": {Name: "t2"}, 55 }, 56 }, 57 "db2": { 58 Name: "db2", 59 Tables: map[string]*checkpoints.TidbTableInfo{ 60 "t3": {Name: "t3"}, 61 }, 62 }, 63 }) 64 c.Assert(err, IsNil) 65 66 // 3. set some checkpoints 67 68 err = cpdb.InsertEngineCheckpoints(ctx, "`db1`.`t2`", map[int32]*checkpoints.EngineCheckpoint{ 69 0: { 70 Status: checkpoints.CheckpointStatusLoaded, 71 Chunks: []*checkpoints.ChunkCheckpoint{{ 72 Key: checkpoints.ChunkCheckpointKey{ 73 Path: "/tmp/path/1.sql", 74 Offset: 0, 75 }, 76 FileMeta: mydump.SourceFileMeta{ 77 Path: "/tmp/path/1.sql", 78 Type: mydump.SourceTypeSQL, 79 FileSize: 12345, 80 }, 81 Chunk: mydump.Chunk{ 82 Offset: 12, 83 EndOffset: 102400, 84 PrevRowIDMax: 1, 85 RowIDMax: 5000, 86 }, 87 }}, 88 }, 89 -1: { 90 Status: checkpoints.CheckpointStatusLoaded, 91 Chunks: nil, 92 }, 93 }) 94 c.Assert(err, IsNil) 95 96 err = cpdb.InsertEngineCheckpoints(ctx, "`db2`.`t3`", map[int32]*checkpoints.EngineCheckpoint{ 97 -1: { 98 Status: checkpoints.CheckpointStatusLoaded, 99 Chunks: nil, 100 }, 101 }) 102 c.Assert(err, IsNil) 103 104 // 4. update some checkpoints 105 106 cpd := checkpoints.NewTableCheckpointDiff() 107 scm := checkpoints.StatusCheckpointMerger{ 108 EngineID: 0, 109 Status: checkpoints.CheckpointStatusImported, 110 } 111 scm.MergeInto(cpd) 112 scm = checkpoints.StatusCheckpointMerger{ 113 EngineID: checkpoints.WholeTableEngineID, 114 Status: checkpoints.CheckpointStatusAllWritten, 115 } 116 scm.MergeInto(cpd) 117 rcm := checkpoints.RebaseCheckpointMerger{ 118 AllocBase: 132861, 119 } 120 rcm.MergeInto(cpd) 121 cksum := checkpoints.TableChecksumMerger{ 122 Checksum: verification.MakeKVChecksum(4492, 686, 486070148910), 123 } 124 cksum.MergeInto(cpd) 125 ccm := checkpoints.ChunkCheckpointMerger{ 126 EngineID: 0, 127 Key: checkpoints.ChunkCheckpointKey{Path: "/tmp/path/1.sql", Offset: 0}, 128 Checksum: verification.MakeKVChecksum(4491, 586, 486070148917), 129 Pos: 55904, 130 RowID: 681, 131 } 132 ccm.MergeInto(cpd) 133 134 cpdb.Update(map[string]*checkpoints.TableCheckpointDiff{"`db1`.`t2`": cpd}) 135 } 136 137 func (s *cpFileSuite) TearDownTest(c *C) { 138 c.Assert(s.cpdb.Close(), IsNil) 139 } 140 141 func (s *cpFileSuite) setInvalidStatus() { 142 cpd := checkpoints.NewTableCheckpointDiff() 143 scm := checkpoints.StatusCheckpointMerger{ 144 EngineID: -1, 145 Status: checkpoints.CheckpointStatusAllWritten, 146 } 147 scm.SetInvalid() 148 scm.MergeInto(cpd) 149 150 s.cpdb.Update(map[string]*checkpoints.TableCheckpointDiff{ 151 "`db1`.`t2`": cpd, 152 "`db2`.`t3`": cpd, 153 }) 154 } 155 156 func (s *cpFileSuite) TestGet(c *C) { 157 ctx := context.Background() 158 159 // 5. get back the checkpoints 160 161 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 162 c.Assert(err, IsNil) 163 c.Assert(cp, DeepEquals, &checkpoints.TableCheckpoint{ 164 Status: checkpoints.CheckpointStatusAllWritten, 165 AllocBase: 132861, 166 Checksum: verification.MakeKVChecksum(4492, 686, 486070148910), 167 Engines: map[int32]*checkpoints.EngineCheckpoint{ 168 -1: { 169 Status: checkpoints.CheckpointStatusLoaded, 170 Chunks: []*checkpoints.ChunkCheckpoint{}, 171 }, 172 0: { 173 Status: checkpoints.CheckpointStatusImported, 174 Chunks: []*checkpoints.ChunkCheckpoint{{ 175 Key: checkpoints.ChunkCheckpointKey{ 176 Path: "/tmp/path/1.sql", 177 Offset: 0, 178 }, 179 FileMeta: mydump.SourceFileMeta{ 180 Path: "/tmp/path/1.sql", 181 Type: mydump.SourceTypeSQL, 182 FileSize: 12345, 183 }, 184 ColumnPermutation: []int{}, 185 Chunk: mydump.Chunk{ 186 Offset: 55904, 187 EndOffset: 102400, 188 PrevRowIDMax: 681, 189 RowIDMax: 5000, 190 }, 191 Checksum: verification.MakeKVChecksum(4491, 586, 486070148917), 192 }}, 193 }, 194 }, 195 }) 196 197 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 198 c.Assert(err, IsNil) 199 c.Assert(cp, DeepEquals, &checkpoints.TableCheckpoint{ 200 Status: checkpoints.CheckpointStatusLoaded, 201 Engines: map[int32]*checkpoints.EngineCheckpoint{ 202 -1: { 203 Status: checkpoints.CheckpointStatusLoaded, 204 Chunks: []*checkpoints.ChunkCheckpoint{}, 205 }, 206 }, 207 }) 208 209 cp, err = s.cpdb.Get(ctx, "`db3`.`not-exists`") 210 c.Assert(cp, IsNil) 211 c.Assert(errors.IsNotFound(err), IsTrue) 212 } 213 214 func (s *cpFileSuite) TestRemoveAllCheckpoints(c *C) { 215 ctx := context.Background() 216 217 err := s.cpdb.RemoveCheckpoint(ctx, "all") 218 c.Assert(err, IsNil) 219 220 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 221 c.Assert(cp, IsNil) 222 c.Assert(errors.IsNotFound(err), IsTrue) 223 224 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 225 c.Assert(cp, IsNil) 226 c.Assert(errors.IsNotFound(err), IsTrue) 227 } 228 229 func (s *cpFileSuite) TestRemoveOneCheckpoint(c *C) { 230 ctx := context.Background() 231 232 err := s.cpdb.RemoveCheckpoint(ctx, "`db1`.`t2`") 233 c.Assert(err, IsNil) 234 235 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 236 c.Assert(cp, IsNil) 237 c.Assert(errors.IsNotFound(err), IsTrue) 238 239 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 240 c.Assert(err, IsNil) 241 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 242 } 243 244 func (s *cpFileSuite) TestIgnoreAllErrorCheckpoints(c *C) { 245 ctx := context.Background() 246 247 s.setInvalidStatus() 248 249 err := s.cpdb.IgnoreErrorCheckpoint(ctx, "all") 250 c.Assert(err, IsNil) 251 252 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 253 c.Assert(err, IsNil) 254 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 255 256 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 257 c.Assert(err, IsNil) 258 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 259 } 260 261 func (s *cpFileSuite) TestIgnoreOneErrorCheckpoints(c *C) { 262 ctx := context.Background() 263 264 s.setInvalidStatus() 265 266 err := s.cpdb.IgnoreErrorCheckpoint(ctx, "`db1`.`t2`") 267 c.Assert(err, IsNil) 268 269 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 270 c.Assert(err, IsNil) 271 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 272 273 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 274 c.Assert(err, IsNil) 275 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusAllWritten/10) 276 } 277 278 func (s *cpFileSuite) TestDestroyAllErrorCheckpoints(c *C) { 279 ctx := context.Background() 280 281 s.setInvalidStatus() 282 283 dtc, err := s.cpdb.DestroyErrorCheckpoint(ctx, "all") 284 c.Assert(err, IsNil) 285 sort.Slice(dtc, func(i, j int) bool { return dtc[i].TableName < dtc[j].TableName }) 286 c.Assert(dtc, DeepEquals, []checkpoints.DestroyedTableCheckpoint{ 287 { 288 TableName: "`db1`.`t2`", 289 MinEngineID: -1, 290 MaxEngineID: 0, 291 }, 292 { 293 TableName: "`db2`.`t3`", 294 MinEngineID: -1, 295 MaxEngineID: -1, 296 }, 297 }) 298 299 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 300 c.Assert(cp, IsNil) 301 c.Assert(errors.IsNotFound(err), IsTrue) 302 303 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 304 c.Assert(cp, IsNil) 305 c.Assert(errors.IsNotFound(err), IsTrue) 306 } 307 308 func (s *cpFileSuite) TestDestroyOneErrorCheckpoint(c *C) { 309 ctx := context.Background() 310 311 s.setInvalidStatus() 312 313 dtc, err := s.cpdb.DestroyErrorCheckpoint(ctx, "`db1`.`t2`") 314 c.Assert(err, IsNil) 315 c.Assert(dtc, DeepEquals, []checkpoints.DestroyedTableCheckpoint{ 316 { 317 TableName: "`db1`.`t2`", 318 MinEngineID: -1, 319 MaxEngineID: 0, 320 }, 321 }) 322 323 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 324 c.Assert(cp, IsNil) 325 c.Assert(errors.IsNotFound(err), IsTrue) 326 327 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 328 c.Assert(err, IsNil) 329 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusAllWritten/10) 330 }