github.com/pingcap/tidb-lightning@v5.0.0-rc.0.20210428090220-84b649866577+incompatible/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 11 "github.com/pingcap/tidb-lightning/lightning/checkpoints" 12 "github.com/pingcap/tidb-lightning/lightning/config" 13 "github.com/pingcap/tidb-lightning/lightning/mydump" 14 "github.com/pingcap/tidb-lightning/lightning/verification" 15 ) 16 17 func Test(t *testing.T) { 18 TestingT(t) 19 } 20 21 var _ = Suite(&cpFileSuite{}) 22 23 type cpFileSuite struct { 24 path string 25 cpdb *checkpoints.FileCheckpointsDB 26 cfg *config.Config 27 } 28 29 func newTestConfig() *config.Config { 30 cfg := config.NewConfig() 31 cfg.Mydumper.SourceDir = "/data" 32 cfg.TaskID = 123 33 cfg.TiDB.Port = 4000 34 cfg.TiDB.PdAddr = "127.0.0.1:2379" 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 ccm := checkpoints.ChunkCheckpointMerger{ 122 EngineID: 0, 123 Key: checkpoints.ChunkCheckpointKey{Path: "/tmp/path/1.sql", Offset: 0}, 124 Checksum: verification.MakeKVChecksum(4491, 586, 486070148917), 125 Pos: 55904, 126 RowID: 681, 127 } 128 ccm.MergeInto(cpd) 129 130 cpdb.Update(map[string]*checkpoints.TableCheckpointDiff{"`db1`.`t2`": cpd}) 131 } 132 133 func (s *cpFileSuite) TearDownTest(c *C) { 134 c.Assert(s.cpdb.Close(), IsNil) 135 } 136 137 func (s *cpFileSuite) setInvalidStatus() { 138 cpd := checkpoints.NewTableCheckpointDiff() 139 scm := checkpoints.StatusCheckpointMerger{ 140 EngineID: -1, 141 Status: checkpoints.CheckpointStatusAllWritten, 142 } 143 scm.SetInvalid() 144 scm.MergeInto(cpd) 145 146 s.cpdb.Update(map[string]*checkpoints.TableCheckpointDiff{ 147 "`db1`.`t2`": cpd, 148 "`db2`.`t3`": cpd, 149 }) 150 } 151 152 func (s *cpFileSuite) TestGet(c *C) { 153 ctx := context.Background() 154 155 // 5. get back the checkpoints 156 157 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 158 c.Assert(err, IsNil) 159 c.Assert(cp, DeepEquals, &checkpoints.TableCheckpoint{ 160 Status: checkpoints.CheckpointStatusAllWritten, 161 AllocBase: 132861, 162 Engines: map[int32]*checkpoints.EngineCheckpoint{ 163 -1: { 164 Status: checkpoints.CheckpointStatusLoaded, 165 Chunks: []*checkpoints.ChunkCheckpoint{}, 166 }, 167 0: { 168 Status: checkpoints.CheckpointStatusImported, 169 Chunks: []*checkpoints.ChunkCheckpoint{{ 170 Key: checkpoints.ChunkCheckpointKey{ 171 Path: "/tmp/path/1.sql", 172 Offset: 0, 173 }, 174 FileMeta: mydump.SourceFileMeta{ 175 Path: "/tmp/path/1.sql", 176 Type: mydump.SourceTypeSQL, 177 FileSize: 12345, 178 }, 179 ColumnPermutation: []int{}, 180 Chunk: mydump.Chunk{ 181 Offset: 55904, 182 EndOffset: 102400, 183 PrevRowIDMax: 681, 184 RowIDMax: 5000, 185 }, 186 Checksum: verification.MakeKVChecksum(4491, 586, 486070148917), 187 }}, 188 }, 189 }, 190 }) 191 192 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 193 c.Assert(err, IsNil) 194 c.Assert(cp, DeepEquals, &checkpoints.TableCheckpoint{ 195 Status: checkpoints.CheckpointStatusLoaded, 196 Engines: map[int32]*checkpoints.EngineCheckpoint{ 197 -1: { 198 Status: checkpoints.CheckpointStatusLoaded, 199 Chunks: []*checkpoints.ChunkCheckpoint{}, 200 }, 201 }, 202 }) 203 204 cp, err = s.cpdb.Get(ctx, "`db3`.`not-exists`") 205 c.Assert(err, IsNil) 206 c.Assert(cp, DeepEquals, &checkpoints.TableCheckpoint{ 207 Engines: make(map[int32]*checkpoints.EngineCheckpoint), 208 }) 209 } 210 211 func (s *cpFileSuite) TestRemoveAllCheckpoints(c *C) { 212 ctx := context.Background() 213 214 err := s.cpdb.RemoveCheckpoint(ctx, "all") 215 c.Assert(err, IsNil) 216 217 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 218 c.Assert(err, IsNil) 219 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusMissing) 220 221 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 222 c.Assert(err, IsNil) 223 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusMissing) 224 } 225 226 func (s *cpFileSuite) TestRemoveOneCheckpoint(c *C) { 227 ctx := context.Background() 228 229 err := s.cpdb.RemoveCheckpoint(ctx, "`db1`.`t2`") 230 c.Assert(err, IsNil) 231 232 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 233 c.Assert(err, IsNil) 234 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusMissing) 235 236 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 237 c.Assert(err, IsNil) 238 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 239 } 240 241 func (s *cpFileSuite) TestIgnoreAllErrorCheckpoints(c *C) { 242 ctx := context.Background() 243 244 s.setInvalidStatus() 245 246 err := s.cpdb.IgnoreErrorCheckpoint(ctx, "all") 247 c.Assert(err, IsNil) 248 249 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 250 c.Assert(err, IsNil) 251 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 252 253 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 254 c.Assert(err, IsNil) 255 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 256 } 257 258 func (s *cpFileSuite) TestIgnoreOneErrorCheckpoints(c *C) { 259 ctx := context.Background() 260 261 s.setInvalidStatus() 262 263 err := s.cpdb.IgnoreErrorCheckpoint(ctx, "`db1`.`t2`") 264 c.Assert(err, IsNil) 265 266 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 267 c.Assert(err, IsNil) 268 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusLoaded) 269 270 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 271 c.Assert(err, IsNil) 272 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusAllWritten/10) 273 } 274 275 func (s *cpFileSuite) TestDestroyAllErrorCheckpoints(c *C) { 276 ctx := context.Background() 277 278 s.setInvalidStatus() 279 280 dtc, err := s.cpdb.DestroyErrorCheckpoint(ctx, "all") 281 c.Assert(err, IsNil) 282 sort.Slice(dtc, func(i, j int) bool { return dtc[i].TableName < dtc[j].TableName }) 283 c.Assert(dtc, DeepEquals, []checkpoints.DestroyedTableCheckpoint{ 284 { 285 TableName: "`db1`.`t2`", 286 MinEngineID: -1, 287 MaxEngineID: 0, 288 }, 289 { 290 TableName: "`db2`.`t3`", 291 MinEngineID: -1, 292 MaxEngineID: -1, 293 }, 294 }) 295 296 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 297 c.Assert(err, IsNil) 298 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusMissing) 299 300 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 301 c.Assert(err, IsNil) 302 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusMissing) 303 } 304 305 func (s *cpFileSuite) TestDestroyOneErrorCheckpoint(c *C) { 306 ctx := context.Background() 307 308 s.setInvalidStatus() 309 310 dtc, err := s.cpdb.DestroyErrorCheckpoint(ctx, "`db1`.`t2`") 311 c.Assert(err, IsNil) 312 c.Assert(dtc, DeepEquals, []checkpoints.DestroyedTableCheckpoint{ 313 { 314 TableName: "`db1`.`t2`", 315 MinEngineID: -1, 316 MaxEngineID: 0, 317 }, 318 }) 319 320 cp, err := s.cpdb.Get(ctx, "`db1`.`t2`") 321 c.Assert(err, IsNil) 322 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusMissing) 323 324 cp, err = s.cpdb.Get(ctx, "`db2`.`t3`") 325 c.Assert(err, IsNil) 326 c.Assert(cp.Status, Equals, checkpoints.CheckpointStatusAllWritten/10) 327 }