Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

backupmeta: add cluster_version and br_version info in backupmeta #734

Merged
merged 19 commits into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712
github.com/pingcap/errors v0.11.5-0.20201126102027-b0a155152ca3
github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce
github.com/pingcap/kvproto v0.0.0-20210204054616-1c1ed89bb167
github.com/pingcap/kvproto v0.0.0-20210204074845-dd36cf2e1c6b
github.com/pingcap/log v0.0.0-20201112100606-8f1e84a3abc8
github.com/pingcap/parser v0.0.0-20210203141130-32ef3e0e2e13
github.com/pingcap/tidb v1.1.0-beta.0.20210223054649-df9e730c167b
Expand Down
2 changes: 2 additions & 0 deletions go.sum1
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ github.com/pingcap/kvproto v0.0.0-20200411081810-b85805c9476c/go.mod h1:IOdRDPLy
github.com/pingcap/kvproto v0.0.0-20200810113304-6157337686b1/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI=
github.com/pingcap/kvproto v0.0.0-20210204054616-1c1ed89bb167 h1:a9nvMHVtsKMXMHxJzCt4vwxf3wD6FD7VSTQQjfhQ11E=
github.com/pingcap/kvproto v0.0.0-20210204054616-1c1ed89bb167/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI=
github.com/pingcap/kvproto v0.0.0-20210204074845-dd36cf2e1c6b h1:bQ4UcbzTFhcBaLRy+kOffTZWgM9DWQSH9VzF0MGm5Os=
github.com/pingcap/kvproto v0.0.0-20210204074845-dd36cf2e1c6b/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI=
github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
Expand Down
11 changes: 10 additions & 1 deletion pkg/backup/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,17 @@ func BuildBackupMeta(
files []*kvproto.File,
rawRanges []*kvproto.RawRange,
ddlJobs []*model.Job,
clusterVersion string,
brVersion string,
) (backupMeta kvproto.BackupMeta, err error) {
backupMeta.StartVersion = req.StartVersion
backupMeta.EndVersion = req.EndVersion
backupMeta.IsRawKv = req.IsRawKv
backupMeta.RawRanges = rawRanges
backupMeta.Files = files
backupMeta.ClusterId = req.ClusterId
backupMeta.ClusterVersion = clusterVersion
backupMeta.BrVersion = brVersion
Comment on lines +194 to +196
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a unit test to tests if these three fields are set correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 7b4365c

backupMeta.Ddls, err = json.Marshal(ddlJobs)
if err != nil {
err = errors.Trace(err)
Expand All @@ -215,6 +220,11 @@ func (bc *Client) SaveBackupMeta(ctx context.Context, backupMeta *kvproto.Backup
return bc.storage.WriteFile(ctx, utils.MetaFile, backupMetaData)
}

// GetClusterID returns the cluster ID of the tidb cluster to backup.
func (bc *Client) GetClusterID() uint64 {
return bc.clusterID
}

// BuildTableRanges returns the key ranges encompassing the entire table,
// and its partitions if exists.
func BuildTableRanges(tbl *model.TableInfo) ([]kv.KeyRange, error) {
Expand Down Expand Up @@ -529,7 +539,6 @@ func (bc *Client) BackupRange(
return nil, errors.Trace(err)
}

req.ClusterId = bc.clusterID
req.StartKey = startKey
req.EndKey = endKey
req.StorageBackend = bc.backend
Expand Down
16 changes: 16 additions & 0 deletions pkg/backup/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/pingcap/br/pkg/backup"
"github.com/pingcap/br/pkg/conn"
"github.com/pingcap/br/pkg/gluetidb"
"github.com/pingcap/br/pkg/pdutil"
)

Expand Down Expand Up @@ -181,3 +182,18 @@ func (r *testBackup) TestOnBackupRegionErrorResponse(c *C) {
}
}
}

func (r *testBackup) TestBuildBackupMeta(c *C) {
req := kvproto.BackupRequest{
ClusterId: r.mockPDClient.GetClusterID(r.ctx),
StartVersion: 0,
EndVersion: 0,
}
clusterVersion := "v4.0.10"
brVersion := gluetidb.New().GetVersion()
backupMeta, err := backup.BuildBackupMeta(&req, nil, nil, nil, clusterVersion, brVersion)
c.Assert(err, IsNil)
c.Assert(backupMeta.ClusterId, Equals, req.ClusterId)
c.Assert(backupMeta.ClusterVersion, Equals, clusterVersion)
c.Assert(backupMeta.BrVersion, Equals, brVersion)
}
3 changes: 3 additions & 0 deletions pkg/glue/glue.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type Glue interface {

// Record records some information useful for log-less summary.
Record(name string, value uint64)

// GetVersion gets the code version to run backup/restore job
lichunzhu marked this conversation as resolved.
Show resolved Hide resolved
GetVersion() string
}

// Session is an abstraction of the session.Session interface.
Expand Down
5 changes: 5 additions & 0 deletions pkg/gluetidb/glue.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ func (g Glue) Record(name string, value uint64) {
g.tikvGlue.Record(name, value)
}

// GetVersion implements glue.Glue.
func (g Glue) GetVersion() string {
return g.tikvGlue.GetVersion()
}

// Execute implements glue.Session.
func (gs *tidbSession) Execute(ctx context.Context, sql string) error {
_, err := gs.se.Execute(ctx, sql)
Expand Down
5 changes: 5 additions & 0 deletions pkg/gluetikv/glue.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,8 @@ func (Glue) StartProgress(ctx context.Context, cmdName string, total int64, redi
func (Glue) Record(name string, val uint64) {
summary.CollectUint(name, val)
}

// GetVersion implements glue.Glue.
func (Glue) GetVersion() string {
return "BR\n" + utils.BRInfo()
}
Comment on lines +60 to +62
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a unit test to make sure the version matches a certain pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 7b4365c

20 changes: 20 additions & 0 deletions pkg/gluetikv/glue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package gluetikv

import (
"testing"

. "github.com/pingcap/check"
)

type testGlue struct{}

var _ = Suite(&testGlue{})

func TestT(t *testing.T) {
TestingT(t)
}

func (r *testGlue) TestGetVersion(c *C) {
g := Glue{}
c.Assert(g.GetVersion(), Matches, "BR(.|\n)*Release Version(.|\n)*Git Commit Hash(.|\n)*")
}
10 changes: 8 additions & 2 deletions pkg/task/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,19 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig
}

req := kvproto.BackupRequest{
ClusterId: client.GetClusterID(),
StartVersion: cfg.LastBackupTS,
EndVersion: backupTS,
RateLimit: cfg.RateLimit,
Concurrency: defaultBackupConcurrency,
CompressionType: cfg.CompressionType,
CompressionLevel: cfg.CompressionLevel,
}
brVersion := g.GetVersion()
clusterVersion, err := mgr.GetClusterVersion(ctx)
if err != nil {
return errors.Trace(err)
}

ranges, backupSchemas, err := backup.BuildBackupRangeAndSchema(
mgr.GetDomain(), mgr.GetStorage(), cfg.TableFilter, backupTS, cfg.IgnoreStats)
Expand All @@ -271,7 +277,7 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig
}
// nothing to backup
if ranges == nil {
backupMeta, err2 := backup.BuildBackupMeta(&req, nil, nil, nil)
backupMeta, err2 := backup.BuildBackupMeta(&req, nil, nil, nil, clusterVersion, brVersion)
if err2 != nil {
return errors.Trace(err2)
}
Expand Down Expand Up @@ -323,7 +329,7 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig
// Backup has finished
updateCh.Close()

backupMeta, err := backup.BuildBackupMeta(&req, files, nil, ddlJobs)
backupMeta, err := backup.BuildBackupMeta(&req, files, nil, ddlJobs, clusterVersion, brVersion)
if err != nil {
return errors.Trace(err)
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/task/backup_raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ func RunBackupRaw(c context.Context, g glue.Glue, cmdName string, cfg *RawKvConf
}
}

brVersion := g.GetVersion()
clusterVersion, err := mgr.GetClusterVersion(ctx)
if err != nil {
return errors.Trace(err)
}

// The number of regions need to backup
approximateRegions, err := mgr.GetRegionCount(ctx, backupRange.StartKey, backupRange.EndKey)
if err != nil {
Expand All @@ -181,6 +187,7 @@ func RunBackupRaw(c context.Context, g glue.Glue, cmdName string, cfg *RawKvConf
ctx, cmdName, int64(approximateRegions), !cfg.LogProgress)

req := kvproto.BackupRequest{
ClusterId: client.GetClusterID(),
StartVersion: 0,
EndVersion: 0,
RateLimit: cfg.RateLimit,
Expand All @@ -199,7 +206,7 @@ func RunBackupRaw(c context.Context, g glue.Glue, cmdName string, cfg *RawKvConf

// Checksum
rawRanges := []*kvproto.RawRange{{StartKey: backupRange.StartKey, EndKey: backupRange.EndKey, Cf: cfg.CF}}
backupMeta, err := backup.BuildBackupMeta(&req, files, rawRanges, nil)
backupMeta, err := backup.BuildBackupMeta(&req, files, rawRanges, nil, clusterVersion, brVersion)
if err != nil {
return errors.Trace(err)
}
Expand Down
83 changes: 83 additions & 0 deletions tests/br_backup_version/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/bash
#
# Copyright 2021 PingCAP, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.

set -eu
DB="$TEST_NAME"

# example
# "cluster_id": 6931331682760961243
expected_cluster_id=`run_curl "https://$PD_ADDR/pd/api/v1/members" | grep "cluster_id"`
# example
#"4.0.10"
expected_cluster_version=`run_curl "https://$PD_ADDR/pd/api/v1/config/cluster-version"`
unset BR_LOG_TO_TERM

function check_version() {
folder=$1
expected_br_version=$2
br_version=`run_br -s "local://$TEST_DIR/$folder" debug decode --field "BrVersion"`
[[ $br_version =~ $expected_br_version ]]
cluster_version=`run_br -s "local://$TEST_DIR/$folder" debug decode --field "ClusterVersion"`
[[ $cluster_version =~ $expected_cluster_version ]]
cluster_id=`run_br -s "local://$TEST_DIR/$folder" debug decode --field "ClusterId" | sed -n -e '1p'`
[[ $expected_cluster_id =~ $cluster_id ]]
}

# backup empty using BR
echo "backup start..."
run_br --pd $PD_ADDR backup full -s "local://$TEST_DIR/br_version_1" --ratelimit 5 --concurrency 4
if [ $? -ne 0 ]; then
echo "TEST: [$TEST_NAME] failed on backup empty cluster version!"
exit 1
fi

check_version "br_version_1" "BR"

# backup empty using BR via SQL
echo "backup start..."
run_sql "BACKUP DATABASE $DB TO \"local://$TEST_DIR/br_version_2\""

# FIXME: uncomment this after TiDB updates this BR dependency
# check_version "br_version_2" "TiDB"

# create a database and insert some data
run_sql "CREATE DATABASE $DB;"
run_sql "CREATE TABLE $DB.usertable1 ( \
YCSB_KEY varchar(64) NOT NULL, \
FIELD0 varchar(1) DEFAULT NULL, \
PRIMARY KEY (YCSB_KEY) \
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"
# insert one row to make sure table is restored.
run_sql "INSERT INTO $DB.usertable1 VALUES (\"a\", \"b\");"

# backup tables using BR
echo "backup start..."
run_br --pd $PD_ADDR backup full -s "local://$TEST_DIR/br_version_3" --ratelimit 5 --concurrency 4
if [ $? -ne 0 ]; then
echo "TEST: [$TEST_NAME] failed on backup empty cluster version!"
exit 1
fi

check_version "br_version_3" "BR"

# backup tables using BR via SQL
echo "backup start..."
run_sql "BACKUP DATABASE $DB TO \"local://$TEST_DIR/br_version_4\""

# FIXME: uncomment this after TiDB updates this BR dependency
# check_version "br_version_4" "TiDB"

run_sql "DROP DATABASE $DB"
echo "TEST: [$TEST_NAME] successed!"