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  }