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  }