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) #804

Closed
Closed
Show file tree
Hide file tree
Changes from all 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
6 changes: 4 additions & 2 deletions go.mod1
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ 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-20201215060142-f3dafca4c7fd
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-20201203152619-33293d112894
github.com/pingcap/tidb v1.1.0-beta.0.20201230023114-f99982b0c594
github.com/pingcap/tidb v1.1.0-beta.0.20210311072255-0651e38a6337
github.com/pingcap/tidb-tools v4.0.9-0.20201127090955-2707c97b3853+incompatible
github.com/pingcap/tipb v0.0.0-20201209065231-aa39b1b86217
github.com/prometheus/client_golang v1.5.1
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/shirou/gopsutil v2.20.6+incompatible // indirect
github.com/sirupsen/logrus v1.6.0
github.com/spf13/cobra v1.0.0
Expand All @@ -31,6 +32,7 @@ require (
go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b
go.uber.org/multierr v1.6.0
go.uber.org/zap v1.16.0
golang.org/x/exp v0.0.0-20200513190911-00229845015e // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
google.golang.org/api v0.22.0
Expand Down
49 changes: 4 additions & 45 deletions go.sum1

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion pkg/backup/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,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
backupMeta.Ddls, err = json.Marshal(ddlJobs)
if err != nil {
err = errors.Trace(err)
Expand All @@ -207,6 +212,11 @@ func (bc *Client) SaveBackupMeta(ctx context.Context, backupMeta *kvproto.Backup
return bc.storage.Write(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 @@ -515,7 +525,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 BR package version to run backup/restore job
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()
}
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 @@ -246,13 +246,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.GetTiKV(), cfg.TableFilter, backupTS, cfg.IgnoreStats)
Expand All @@ -261,7 +267,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 @@ -313,7 +319,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 @@ -160,6 +160,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 @@ -174,6 +180,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 @@ -192,7 +199,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!"