github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/restore/util_test.go (about)

     1  // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0.
     2  
     3  package restore_test
     4  
     5  import (
     6  	"context"
     7  	"encoding/binary"
     8  
     9  	. "github.com/pingcap/check"
    10  	backuppb "github.com/pingcap/kvproto/pkg/backup"
    11  	"github.com/pingcap/kvproto/pkg/import_sstpb"
    12  	"github.com/pingcap/kvproto/pkg/metapb"
    13  	"github.com/pingcap/tidb/tablecodec"
    14  	"github.com/pingcap/tidb/util/codec"
    15  
    16  	"github.com/pingcap/br/pkg/restore"
    17  )
    18  
    19  var _ = Suite(&testRestoreUtilSuite{})
    20  
    21  type testRestoreUtilSuite struct {
    22  }
    23  
    24  func (s *testRestoreUtilSuite) TestParseQuoteName(c *C) {
    25  	schema, table := restore.ParseQuoteName("`a`.`b`")
    26  	c.Assert(schema, Equals, "a")
    27  	c.Assert(table, Equals, "b")
    28  
    29  	schema, table = restore.ParseQuoteName("`a``b`.``````")
    30  	c.Assert(schema, Equals, "a`b")
    31  	c.Assert(table, Equals, "``")
    32  
    33  	schema, table = restore.ParseQuoteName("`.`.`.`")
    34  	c.Assert(schema, Equals, ".")
    35  	c.Assert(table, Equals, ".")
    36  
    37  	schema, table = restore.ParseQuoteName("`.``.`.`.`")
    38  	c.Assert(schema, Equals, ".`.")
    39  	c.Assert(table, Equals, ".")
    40  }
    41  
    42  func (s *testRestoreUtilSuite) TestGetSSTMetaFromFile(c *C) {
    43  	file := &backuppb.File{
    44  		Name:     "file_write.sst",
    45  		StartKey: []byte("t1a"),
    46  		EndKey:   []byte("t1ccc"),
    47  	}
    48  	rule := &import_sstpb.RewriteRule{
    49  		OldKeyPrefix: []byte("t1"),
    50  		NewKeyPrefix: []byte("t2"),
    51  	}
    52  	region := &metapb.Region{
    53  		StartKey: []byte("t2abc"),
    54  		EndKey:   []byte("t3a"),
    55  	}
    56  	sstMeta := restore.GetSSTMetaFromFile([]byte{}, file, region, rule)
    57  	c.Assert(string(sstMeta.GetRange().GetStart()), Equals, "t2abc")
    58  	c.Assert(string(sstMeta.GetRange().GetEnd()), Equals, "t2\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")
    59  }
    60  
    61  func (s *testRestoreUtilSuite) TestMapTableToFiles(c *C) {
    62  	filesOfTable1 := []*backuppb.File{
    63  		{
    64  			Name:     "table1-1.sst",
    65  			StartKey: tablecodec.EncodeTablePrefix(1),
    66  			EndKey:   tablecodec.EncodeTablePrefix(1),
    67  		},
    68  		{
    69  			Name:     "table1-2.sst",
    70  			StartKey: tablecodec.EncodeTablePrefix(1),
    71  			EndKey:   tablecodec.EncodeTablePrefix(1),
    72  		},
    73  		{
    74  			Name:     "table1-3.sst",
    75  			StartKey: tablecodec.EncodeTablePrefix(1),
    76  			EndKey:   tablecodec.EncodeTablePrefix(1),
    77  		},
    78  	}
    79  	filesOfTable2 := []*backuppb.File{
    80  		{
    81  			Name:     "table2-1.sst",
    82  			StartKey: tablecodec.EncodeTablePrefix(2),
    83  			EndKey:   tablecodec.EncodeTablePrefix(2),
    84  		},
    85  		{
    86  			Name:     "table2-2.sst",
    87  			StartKey: tablecodec.EncodeTablePrefix(2),
    88  			EndKey:   tablecodec.EncodeTablePrefix(2),
    89  		},
    90  	}
    91  
    92  	result := restore.MapTableToFiles(append(filesOfTable2, filesOfTable1...))
    93  
    94  	c.Assert(result[1], DeepEquals, filesOfTable1)
    95  	c.Assert(result[2], DeepEquals, filesOfTable2)
    96  }
    97  
    98  func (s *testRestoreUtilSuite) TestValidateFileRewriteRule(c *C) {
    99  	rules := &restore.RewriteRules{
   100  		Data: []*import_sstpb.RewriteRule{{
   101  			OldKeyPrefix: []byte(tablecodec.EncodeTablePrefix(1)),
   102  			NewKeyPrefix: []byte(tablecodec.EncodeTablePrefix(2)),
   103  		}},
   104  	}
   105  
   106  	// Empty start/end key is not allowed.
   107  	err := restore.ValidateFileRewriteRule(
   108  		&backuppb.File{
   109  			Name:     "file_write.sst",
   110  			StartKey: []byte(""),
   111  			EndKey:   []byte(""),
   112  		},
   113  		rules,
   114  	)
   115  	c.Assert(err, ErrorMatches, ".*cannot find rewrite rule.*")
   116  
   117  	// Range is not overlap, no rule found.
   118  	err = restore.ValidateFileRewriteRule(
   119  		&backuppb.File{
   120  			Name:     "file_write.sst",
   121  			StartKey: tablecodec.EncodeTablePrefix(0),
   122  			EndKey:   tablecodec.EncodeTablePrefix(1),
   123  		},
   124  		rules,
   125  	)
   126  	c.Assert(err, ErrorMatches, ".*cannot find rewrite rule.*")
   127  
   128  	// No rule for end key.
   129  	err = restore.ValidateFileRewriteRule(
   130  		&backuppb.File{
   131  			Name:     "file_write.sst",
   132  			StartKey: tablecodec.EncodeTablePrefix(1),
   133  			EndKey:   tablecodec.EncodeTablePrefix(2),
   134  		},
   135  		rules,
   136  	)
   137  	c.Assert(err, ErrorMatches, ".*cannot find rewrite rule.*")
   138  
   139  	// Add a rule for end key.
   140  	rules.Data = append(rules.Data, &import_sstpb.RewriteRule{
   141  		OldKeyPrefix: tablecodec.EncodeTablePrefix(2),
   142  		NewKeyPrefix: tablecodec.EncodeTablePrefix(3),
   143  	})
   144  	err = restore.ValidateFileRewriteRule(
   145  		&backuppb.File{
   146  			Name:     "file_write.sst",
   147  			StartKey: tablecodec.EncodeTablePrefix(1),
   148  			EndKey:   tablecodec.EncodeTablePrefix(2),
   149  		},
   150  		rules,
   151  	)
   152  	c.Assert(err, ErrorMatches, ".*restore table ID mismatch")
   153  
   154  	// Add a bad rule for end key, after rewrite start key > end key.
   155  	rules.Data = append(rules.Data[:1], &import_sstpb.RewriteRule{
   156  		OldKeyPrefix: tablecodec.EncodeTablePrefix(2),
   157  		NewKeyPrefix: tablecodec.EncodeTablePrefix(1),
   158  	})
   159  	err = restore.ValidateFileRewriteRule(
   160  		&backuppb.File{
   161  			Name:     "file_write.sst",
   162  			StartKey: tablecodec.EncodeTablePrefix(1),
   163  			EndKey:   tablecodec.EncodeTablePrefix(2),
   164  		},
   165  		rules,
   166  	)
   167  	c.Assert(err, ErrorMatches, ".*unexpected rewrite rules.*")
   168  }
   169  
   170  func (s *testRestoreUtilSuite) TestPaginateScanRegion(c *C) {
   171  	peers := make([]*metapb.Peer, 1)
   172  	peers[0] = &metapb.Peer{
   173  		Id:      1,
   174  		StoreId: 1,
   175  	}
   176  	stores := make(map[uint64]*metapb.Store)
   177  	stores[1] = &metapb.Store{
   178  		Id: 1,
   179  	}
   180  
   181  	makeRegions := func(num uint64) (map[uint64]*restore.RegionInfo, []*restore.RegionInfo) {
   182  		regionsMap := make(map[uint64]*restore.RegionInfo, num)
   183  		regions := make([]*restore.RegionInfo, 0, num)
   184  		endKey := make([]byte, 8)
   185  		for i := uint64(0); i < num-1; i++ {
   186  			ri := &restore.RegionInfo{
   187  				Region: &metapb.Region{
   188  					Id:    i + 1,
   189  					Peers: peers,
   190  				},
   191  			}
   192  
   193  			if i != 0 {
   194  				startKey := make([]byte, 8)
   195  				binary.BigEndian.PutUint64(startKey, i)
   196  				ri.Region.StartKey = codec.EncodeBytes([]byte{}, startKey)
   197  			}
   198  			endKey = make([]byte, 8)
   199  			binary.BigEndian.PutUint64(endKey, i+1)
   200  			ri.Region.EndKey = codec.EncodeBytes([]byte{}, endKey)
   201  
   202  			regionsMap[i] = ri
   203  			regions = append(regions, ri)
   204  		}
   205  
   206  		if num == 1 {
   207  			endKey = []byte{}
   208  		} else {
   209  			endKey = codec.EncodeBytes([]byte{}, endKey)
   210  		}
   211  		ri := &restore.RegionInfo{
   212  			Region: &metapb.Region{
   213  				Id:       num,
   214  				Peers:    peers,
   215  				StartKey: endKey,
   216  				EndKey:   []byte{},
   217  			},
   218  		}
   219  		regionsMap[num] = ri
   220  		regions = append(regions, ri)
   221  
   222  		return regionsMap, regions
   223  	}
   224  
   225  	ctx := context.Background()
   226  	regionMap := make(map[uint64]*restore.RegionInfo)
   227  	regions := []*restore.RegionInfo{}
   228  	batch, err := restore.PaginateScanRegion(ctx, NewTestClient(stores, regionMap, 0), []byte{}, []byte{}, 3)
   229  	c.Assert(err, IsNil)
   230  	c.Assert(batch, DeepEquals, regions)
   231  
   232  	regionMap, regions = makeRegions(1)
   233  	batch, err = restore.PaginateScanRegion(ctx, NewTestClient(stores, regionMap, 0), []byte{}, []byte{}, 3)
   234  	c.Assert(err, IsNil)
   235  	c.Assert(batch, DeepEquals, regions)
   236  
   237  	regionMap, regions = makeRegions(2)
   238  	batch, err = restore.PaginateScanRegion(ctx, NewTestClient(stores, regionMap, 0), []byte{}, []byte{}, 3)
   239  	c.Assert(err, IsNil)
   240  	c.Assert(batch, DeepEquals, regions)
   241  
   242  	regionMap, regions = makeRegions(3)
   243  	batch, err = restore.PaginateScanRegion(ctx, NewTestClient(stores, regionMap, 0), []byte{}, []byte{}, 3)
   244  	c.Assert(err, IsNil)
   245  	c.Assert(batch, DeepEquals, regions)
   246  
   247  	regionMap, regions = makeRegions(8)
   248  	batch, err = restore.PaginateScanRegion(ctx, NewTestClient(stores, regionMap, 0), []byte{}, []byte{}, 3)
   249  	c.Assert(err, IsNil)
   250  	c.Assert(batch, DeepEquals, regions)
   251  
   252  	regionMap, regions = makeRegions(8)
   253  	batch, err = restore.PaginateScanRegion(
   254  		ctx, NewTestClient(stores, regionMap, 0), regions[1].Region.StartKey, []byte{}, 3)
   255  	c.Assert(err, IsNil)
   256  	c.Assert(batch, DeepEquals, regions[1:])
   257  
   258  	batch, err = restore.PaginateScanRegion(
   259  		ctx, NewTestClient(stores, regionMap, 0), []byte{}, regions[6].Region.EndKey, 3)
   260  	c.Assert(err, IsNil)
   261  	c.Assert(batch, DeepEquals, regions[:7])
   262  
   263  	batch, err = restore.PaginateScanRegion(
   264  		ctx, NewTestClient(stores, regionMap, 0), regions[1].Region.StartKey, regions[1].Region.EndKey, 3)
   265  	c.Assert(err, IsNil)
   266  	c.Assert(batch, DeepEquals, regions[1:2])
   267  
   268  	_, err = restore.PaginateScanRegion(ctx, NewTestClient(stores, regionMap, 0), []byte{2}, []byte{1}, 3)
   269  	c.Assert(err, ErrorMatches, ".*startKey >= endKey.*")
   270  }