diff --git a/.github/workflows/check-and-build.yml b/.github/workflows/check-and-build.yml index 0d102cc5eb..6661612073 100644 --- a/.github/workflows/check-and-build.yml +++ b/.github/workflows/check-and-build.yml @@ -43,7 +43,7 @@ jobs: key: ${{ runner.os }}-dm-tools-${{ hashFiles('**/tools/go.sum') }} - name: Build - run: make build + run: make build nolint=true lint: name: Lint @@ -56,11 +56,5 @@ jobs: - name: GolangCI Lint uses: golangci/golangci-lint-action@v2 with: - version: v1.31 - args: --timeout 10m0s --skip-dirs ^_tool/ - - - name: Revive Lint - uses: morphy2k/revive-action@v1 - with: - config: .revive.toml - exclude: _tool/... + version: latest + args: --config .golangci.yml --timeout 10m0s --skip-dirs ^_tool/ diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000000..beaae2ad00 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,123 @@ +linters: + disable-all: true + enable: + - asciicheck + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + - errcheck + - exportloopref + - gocritic + - godot + - golint + - goprintffuncname + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - noctx + - nolintlint + - prealloc + - revive + - rowserrcheck + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace + - durationcheck + - gofumpt + - goheader + - gomodguard + - ifshort + - importas + - makezero + - nilerr + - predeclared + - sqlclosecheck + - thelper + - tparallel + - wastedassign + + # don't enable: + # - testpackage + # - lll + # - wsl + # - gochecknoglobals + # - godox + # - gomnd + # - goerr113 + # - exhaustive + # - wrapcheck + # - nlreturn + # - exhaustivestruct + # - errorlint + # - forcetypeassert + # - paralleltest + # - forbidigo + # - gosec + # - goconst + # - interfacer + # - scopelint + + # already cover: + # - gci + # - goimports + # - gofmt + + # better to fix them + # - funlen + # - gocognit + # - nestif + # - gocyclo + # - cyclop + # - gomoddirectives + # - gochecknoinits + # - maligned + +linters-settings: + govet: + # report about shadowed variables + check-shadowing: true + revive: + ignoreGeneratedHeader: false + severity: "error" + confidence: 0.8 + errorCode: -1 + warningCode: -1 + rules: + - name: blank-imports + - name: context-as-argument + - name: dot-imports + - name: error-return + - name: error-strings + - name: error-naming + - name: exported + - name: if-return + - name: var-naming + - name: package-comments + - name: range + - name: receiver-naming + - name: indent-error-flow + - name: superfluous-else + - name: modifies-parameter + - name: unreachable-code + +issues: + include: + - EXC0002 # golint + - EXC0003 + + # Fix found issues (if it's supported by the linter) + fix: true + +run: + # timeout for analysis, e.g. 30s, 5m, default is 1m + timeout: 5m \ No newline at end of file diff --git a/.revive.toml b/.revive.toml deleted file mode 100644 index 2ec83a6456..0000000000 --- a/.revive.toml +++ /dev/null @@ -1,24 +0,0 @@ -ignoreGeneratedHeader = false -severity = "error" -confidence = 0.8 -errorCode = -1 -warningCode = -1 - -[rule.blank-imports] -[rule.context-as-argument] -[rule.dot-imports] -[rule.error-return] -[rule.error-strings] -[rule.error-naming] -[rule.exported] -[rule.if-return] -[rule.var-naming] -[rule.package-comments] -[rule.range] -[rule.receiver-naming] -[rule.indent-error-flow] -[rule.superfluous-else] -[rule.modifies-parameter] - -# This can be checked by other tools like megacheck -[rule.unreachable-code] diff --git a/Makefile b/Makefile index 0a5e4b50ba..d1ac334667 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,9 @@ CURDIR := $(shell pwd) GO := GO111MODULE=on go GOBUILD := CGO_ENABLED=0 $(GO) build GOTEST := CGO_ENABLED=1 $(GO) test +PACKAGE_NAME := github.com/pingcap/dm PACKAGES := $$(go list ./... | grep -vE 'tests|cmd|vendor|pb|pbmock|_tools') +PACKAGE_DIRECTORIES := $$(echo "$(PACKAGES)" | sed 's/github.com\/pingcap\/dm\/*//') PACKAGES_RELAY := $$(go list ./... | grep 'github.com/pingcap/dm/relay') PACKAGES_SYNCER := $$(go list ./... | grep 'github.com/pingcap/dm/syncer') PACKAGES_PKG_BINLOG := $$(go list ./... | grep 'github.com/pingcap/dm/pkg/binlog') @@ -80,15 +82,7 @@ dm-portal-frontend: tools_setup: @echo "setup tools" - cd tools && $(GOBUILD) -o bin/errcheck github.com/kisielk/errcheck - cd tools && $(GOBUILD) -o bin/failpoint-ctl github.com/pingcap/failpoint/failpoint-ctl - cd tools && $(GOBUILD) -o bin/gocovmerge github.com/zhouqiang-cl/gocovmerge - cd tools && $(GOBUILD) -o bin/golint golang.org/x/lint/golint - cd tools && $(GOBUILD) -o bin/goveralls github.com/mattn/goveralls - cd tools && $(GOBUILD) -o bin/mockgen github.com/golang/mock/mockgen - cd tools && $(GOBUILD) -o bin/protoc-gen-gogofaster github.com/gogo/protobuf/protoc-gen-gogofaster - cd tools && $(GOBUILD) -o bin/protoc-gen-grpc-gateway github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway - cd tools && $(GOBUILD) -o bin/statik github.com/rakyll/statik + @cd tools && make generate_proto: tools_setup ./generate-dm.sh @@ -128,25 +122,17 @@ unit_test_pkg_binlog: tools_setup unit_test_others: tools_setup $(call run_unit_test,$(PACKAGES_OTHERS),unit_test_others) -check: tools_setup fmt lint vet terror_check tidy_mod +check: tools_setup fmt lint terror_check tidy_mod fmt: - @echo "gofmt (simplify)" - @ gofmt -s -l -w $(FILES) 2>&1 | awk '{print} END{if(NR>0) {exit 1}}' - -errcheck: tools_setup - @echo "errcheck" - tools/bin/errcheck -blank $(PACKAGES) | grep -v "_test\.go" | awk '{print} END{if(NR>0) {exit 1}}' + @echo "gofumports" + tools/bin/gofumports -w -d -local $(PACKAGE_NAME) $(PACKAGE_DIRECTORIES) 2>&1 | awk '{print} END{if(NR>0) {exit 1}}' lint: tools_setup - @echo "golint" - tools/bin/golint -set_exit_status $(PACKAGES) - -vet: - $(GO) build -o bin/shadow golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow - @echo "vet" - @$(GO) vet -composites=false $(PACKAGES) - @$(GO) vet -vettool=$(CURDIR)/bin/shadow $(PACKAGES) || true + @if [[ "${nolint}" != "true" ]]; then\ + echo "golangci-lint"; \ + tools/bin/golangci-lint run --config=$(CURDIR)/.golangci.yml --issues-exit-code=1 $(PACKAGE_DIRECTORIES); \ + fi terror_check: @echo "check terror conflict" @@ -154,7 +140,8 @@ terror_check: tidy_mod: @echo "tidy go.mod" - _utils/mod_check/check.sh + $(GO) mod tidy + git diff --exit-code go.mod go.sum dm_integration_test_build: tools_setup $(FAILPOINT_ENABLE) @@ -209,14 +196,6 @@ else go tool cover -html "$(TEST_DIR)/unit_test.out" -o "$(TEST_DIR)/unit_test_cov.html" endif -check-static: - @echo "gometalinter" - gometalinter --disable-all --deadline 120s \ - --enable misspell \ - --enable megacheck \ - --enable ineffassign \ - ./... - failpoint-enable: tools_setup $(FAILPOINT_ENABLE) diff --git a/_utils/mod_check/check.sh b/_utils/mod_check/check.sh deleted file mode 100755 index e5f9c29025..0000000000 --- a/_utils/mod_check/check.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -eu - -CUR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) - -trap "cd $PWD" EXIT -GO111MODULE=on go mod tidy -git diff --exit-code -- go.mod go.sum diff --git a/chaos/cases/config.go b/chaos/cases/config.go index 5c6c43bf53..dde077c293 100644 --- a/chaos/cases/config.go +++ b/chaos/cases/config.go @@ -75,8 +75,7 @@ func newConfig() *config { // parse parses flag definitions from the argument list. func (c *config) parse(args []string) error { - err := c.FlagSet.Parse(args) - if err != nil { + if err := c.FlagSet.Parse(args); err != nil { return err } diff --git a/chaos/cases/generator.go b/chaos/cases/generator.go index 2857c21fc4..347e051f0c 100644 --- a/chaos/cases/generator.go +++ b/chaos/cases/generator.go @@ -40,7 +40,7 @@ type SQLs []SQL type Case []SQLs var ( - // add some flags column, so we can make sure the order of new column in optimsitic + // add some flags column, so we can make sure the order of new column in optimsitic. preSQLs1 = SQLs{ {"ALTER TABLE %s.%s ADD COLUMN case3_flag1 INT, ADD COLUMN case3_flag2 INT, ADD COLUMN case3_flag3 INT", source1}, {"ALTER TABLE %s.%s ADD COLUMN case3_flag1 INT, ADD COLUMN case3_flag2 INT, ADD COLUMN case3_flag3 INT", source2}, @@ -56,7 +56,7 @@ var ( {"ALTER TABLE %s.%s ADD COLUMN case9_flag INT;", source3}, } - // ALL ADD COLUMN, ALL DROP COLUMN + // ALL ADD COLUMN, ALL DROP COLUMN. case1 = Case{ {{"ALTER TABLE %s.%s ADD COLUMN case1 INT;", source1}}, {{"ALTER TABLE %s.%s ADD COLUMN case1 INT;", source2}}, @@ -65,12 +65,12 @@ var ( {{"ALTER TABLE %s.%s DROP COLUMN case1;", source2}}, {{"ALTER TABLE %s.%s DROP COLUMN case1;", source3}}, } - // ADD COLUMN, DROP COLUMN for one source + // ADD COLUMN, DROP COLUMN for one source. case2 = Case{ {{"ALTER TABLE %s.%s ADD COLUMN case2 INT;", source1}}, {{"ALTER TABLE %s.%s DROP COLUMN case2;", source1}}, } - // ADD columns out of order + // ADD columns out of order. case3 = Case{ { {"ALTER TABLE %s.%s DROP COLUMN case3_1;", source1}, @@ -93,7 +93,7 @@ var ( {{"ALTER TABLE %s.%s ADD COLUMN case3_1 INT AFTER case3_flag1;", source2}}, {{"ALTER TABLE %s.%s ADD COLUMN case3_2 INT AFTER case3_flag2;", source3}}, } - // MULTIPLE ADD COLUMN out of order + // MULTIPLE ADD COLUMN out of order. case4 = Case{ { {"ALTER TABLE %s.%s DROP COLUMN case4_1, DROP COLUMN case4_2, DROP COLUMN case4_3;", source1}, @@ -104,7 +104,7 @@ var ( {{"ALTER TABLE %s.%s ADD COLUMN case4_2 INT AFTER case4_flag2, ADD COLUMN case4_3 INT AFTER case4_flag3, ADD COLUMN case4_1 INT AFTER case4_flag1;", source2}}, {{"ALTER TABLE %s.%s ADD COLUMN case4_3 INT AFTER case4_flag3, ADD COLUMN case4_1 INT AFTER case4_flag1, ADD COLUMN case4_2 INT AFTER case4_flag2;", source3}}, } - // MULTIPLE ADD COLUMN vs ADD columns + // MULTIPLE ADD COLUMN vs ADD columns. case5 = Case{ { {"ALTER TABLE %s.%s DROP COLUMN case5_1;", source1}, @@ -123,7 +123,7 @@ var ( {{"ALTER TABLE %s.%s ADD COLUMN case5_3 INT AFTER case5_flag3;", source2}}, {{"ALTER TABLE %s.%s ADD COLUMN case5_2 INT AFTER case5_flag2, ADD COLUMN case5_3 INT AFTER case5_flag3;", source1}}, } - // ALL ADD INDEX, ALL DROP INDEX + // ALL ADD INDEX, ALL DROP INDEX. case6 = Case{ {{"ALTER TABLE %s.%s ADD INDEX case6_idx(case3_flag1);", source1}}, {{"ALTER TABLE %s.%s ADD INDEX case6_idx(case3_flag1);", source2}}, @@ -132,12 +132,12 @@ var ( {{"ALTER TABLE %s.%s DROP INDEX case6_idx;", source2}}, {{"ALTER TABLE %s.%s DROP INDEX case6_idx;", source3}}, } - // ADD INDEX, DROP INDEX for one source + // ADD INDEX, DROP INDEX for one source. case7 = Case{ {{"ALTER TABLE %s.%s ADD INDEX case7_idx(uuid);", source1}}, {{"ALTER TABLE %s.%s DROP INDEX case7_idx;", source1}}, } - // ADD MULTI-COLUMN INDEX + // ADD MULTI-COLUMN INDEX. case8 = Case{ { {"ALTER TABLE %s.%s DROP INDEX case8_idx;", source1}, @@ -148,7 +148,7 @@ var ( {{"ALTER TABLE %s.%s ADD INDEX case8_idx(case4_flag1, case4_flag2, case4_flag3);", source2}}, {{"ALTER TABLE %s.%s ADD INDEX case8_idx(case4_flag1, case4_flag2, case4_flag3);", source3}}, } - // ADD COLUMN AND INDEX + // ADD COLUMN AND INDEX. case9 = Case{ { {"ALTER TABLE %s.%s DROP INDEX case9_idx;", source1}, @@ -206,7 +206,7 @@ func NewCaseGenerator(shardMode string) *CaseGenerator { return g } -// Start starts to generate sqls case +// Start starts to generate sqls case. func (g *CaseGenerator) Start(ctx context.Context, schema string, tables []string) { g.schema = schema g.tables = tables @@ -238,12 +238,12 @@ func (g *CaseGenerator) genSQLs(ctx context.Context) { } } -// GetSQLs gets sql from CaseGenerator +// GetSQLs gets sql from CaseGenerator. func (g *CaseGenerator) GetSQLs() SQLs { return <-g.sqlsChan } -// GetPreSQLs gets preSQLs from CaseGenerator +// GetPreSQLs gets preSQLs from CaseGenerator. func (g *CaseGenerator) GetPreSQLs() SQLs { testPreSQLs := make(SQLs, 0, len(g.testPreSQLs)*len(g.tables)) for _, table := range g.tables { diff --git a/chaos/cases/instance.go b/chaos/cases/instance.go index 20181505a4..90eed445b0 100644 --- a/chaos/cases/instance.go +++ b/chaos/cases/instance.go @@ -20,12 +20,10 @@ import ( "github.com/pingcap/dm/pkg/conn" ) -var ( - // set lesser sql_mode to tolerate some SQLs generated by go-sqlsmith. - mustExecSQLs = []string{ - `SET @@GLOBAL.SQL_MODE="NO_ENGINE_SUBSTITUTION"`, - } -) +// set lesser sql_mode to tolerate some SQLs generated by go-sqlsmith. +var mustExecSQLs = []string{ + `SET @@GLOBAL.SQL_MODE="NO_ENGINE_SUBSTITUTION"`, +} // setInstancesState sets the state (like global sql_mode) for upstream and downstream DB instances. func setInstancesState(ctx context.Context, targetCfg config2.DBConfig, sourcesCfg ...config2.DBConfig) error { diff --git a/chaos/cases/main.go b/chaos/cases/main.go index 3055b1cd40..8e754567ac 100644 --- a/chaos/cases/main.go +++ b/chaos/cases/main.go @@ -19,7 +19,6 @@ import ( "fmt" "math/rand" "net/http" - _ "net/http/pprof" "os" "os/signal" "syscall" @@ -36,21 +35,28 @@ import ( // main starts to run the test case logic after MySQL, TiDB and DM have been set up. // NOTE: run this in the same K8s namespace as DM-master. func main() { + code := 0 + defer func() { + os.Exit(code) + }() + cfg := newConfig() err := cfg.parse(os.Args[1:]) switch errors.Cause(err) { case nil: case flag.ErrHelp: - os.Exit(0) + return default: fmt.Println("parse cmd flags err:", err.Error()) - os.Exit(2) + code = 2 + return } err = log.InitLogger(&log.Config{Level: "info"}) if err != nil { fmt.Println("init logger error:", err.Error()) - os.Exit(2) + code = 2 + return } go func() { @@ -80,7 +86,8 @@ func main() { masterConn, err := grpc.DialContext(ctx2, cfg.MasterAddr, grpc.WithBlock(), grpc.WithInsecure()) // no TLS support in chaos cases now. if err != nil { log.L().Error("fail to dail DM-master", zap.String("address", cfg.MasterAddr), zap.Error(err)) - os.Exit(2) + code = 2 + return } masterCli := pb.NewMasterClient(masterConn) @@ -94,14 +101,16 @@ func main() { err = createSources(ctx, masterCli, cfg) if err != nil { log.L().Error("fail to create source", zap.Error(err)) - os.Exit(2) + code = 2 + return } // set upstream and downstream instances state. err = setInstancesState(ctx, cfg.Target, cfg.Source1, cfg.Source2, cfg.Source3) if err != nil { log.L().Error("fail to set instances state", zap.Error(err)) - os.Exit(2) + code = 2 + return } // context for the duration of running. @@ -112,6 +121,7 @@ func main() { err = runCases(ctx3, masterCli, cfg.ConfigDir, cfg.Target, cfg.Source1, cfg.Source2, cfg.Source3) if err != nil { log.L().Error("run cases failed", zap.Error(err)) - os.Exit(2) + code = 2 + return } } diff --git a/chaos/cases/task.go b/chaos/cases/task.go index 016be507a2..a983b7200f 100644 --- a/chaos/cases/task.go +++ b/chaos/cases/task.go @@ -27,12 +27,13 @@ import ( "go.uber.org/zap" "golang.org/x/sync/errgroup" + "github.com/pingcap/tidb-tools/pkg/dbutil" + config2 "github.com/pingcap/dm/dm/config" "github.com/pingcap/dm/dm/pb" "github.com/pingcap/dm/pkg/conn" "github.com/pingcap/dm/pkg/log" "github.com/pingcap/dm/pkg/utils" - "github.com/pingcap/tidb-tools/pkg/dbutil" ) const ( diff --git a/checker/check_test.go b/checker/check_test.go index 734cf30740..74df44be93 100644 --- a/checker/check_test.go +++ b/checker/check_test.go @@ -20,9 +20,10 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + router "github.com/pingcap/tidb-tools/pkg/table-router" + "github.com/pingcap/dm/dm/config" "github.com/pingcap/dm/pkg/conn" - router "github.com/pingcap/tidb-tools/pkg/table-router" tc "github.com/pingcap/check" ) @@ -39,7 +40,7 @@ type mockDBProvider struct { db *sql.DB } -// Apply will build BaseDB with DBConfig +// Apply will build BaseDB with DBConfig. func (d *mockDBProvider) Apply(config config.DBConfig) (*conn.BaseDB, error) { return conn.NewBaseDB(d.db, func() {}), nil } @@ -227,15 +228,17 @@ func (s *testCheckerSuite) TestBinlogRowImageChecking(c *tc.C) { } func (s *testCheckerSuite) TestTableSchemaChecking(c *tc.C) { + var ( + schema = "db_1" + tb1 = "t_1" + tb2 = "t_2" + ) cfgs := []*config.SubTaskConfig{ { IgnoreCheckingItems: ignoreExcept(map[string]struct{}{config.TableSchemaChecking: {}}), }, } - schema := "db_1" - tb1 := "t_1" - tb2 := "t_2" createTable1 := `CREATE TABLE %s ( id int(11) DEFAULT NULL, b int(11) DEFAULT NULL @@ -266,11 +269,16 @@ func (s *testCheckerSuite) TestTableSchemaChecking(c *tc.C) { } func (s *testCheckerSuite) TestShardTableSchemaChecking(c *tc.C) { + var ( + schema = "db_1" + tb1 = "t_1" + tb2 = "t_2" + ) cfgs := []*config.SubTaskConfig{ { RouteRules: []*router.TableRule{ { - SchemaPattern: "db_1", + SchemaPattern: schema, TargetSchema: "db", TablePattern: "t_*", TargetTable: "t", @@ -280,9 +288,6 @@ func (s *testCheckerSuite) TestShardTableSchemaChecking(c *tc.C) { }, } - schema := "db_1" - tb1 := "t_1" - tb2 := "t_2" createTable1 := `CREATE TABLE %s ( id int(11) DEFAULT NULL, b int(11) DEFAULT NULL @@ -310,11 +315,16 @@ func (s *testCheckerSuite) TestShardTableSchemaChecking(c *tc.C) { } func (s *testCheckerSuite) TestShardAutoIncrementIDChecking(c *tc.C) { + var ( + schema = "db_1" + tb1 = "t_1" + tb2 = "t_2" + ) cfgs := []*config.SubTaskConfig{ { RouteRules: []*router.TableRule{ { - SchemaPattern: "db_1", + SchemaPattern: schema, TargetSchema: "db", TablePattern: "t_*", TargetTable: "t", @@ -324,9 +334,6 @@ func (s *testCheckerSuite) TestShardAutoIncrementIDChecking(c *tc.C) { }, } - schema := "db_1" - tb1 := "t_1" - tb2 := "t_2" createTable1 := `CREATE TABLE %s ( id int(11) NOT NULL AUTO_INCREMENT, b int(11) DEFAULT NULL, @@ -359,18 +366,23 @@ func (s *testCheckerSuite) TestShardAutoIncrementIDChecking(c *tc.C) { } func (s *testCheckerSuite) TestSameTargetTableDetection(c *tc.C) { + var ( + schema = "db_1" + tb1 = "t_1" + tb2 = "t_2" + ) cfgs := []*config.SubTaskConfig{ { RouteRules: []*router.TableRule{ { - SchemaPattern: "db_1", + SchemaPattern: schema, TargetSchema: "db", - TablePattern: "t_1", + TablePattern: tb1, TargetTable: "t", }, { - SchemaPattern: "db_1", + SchemaPattern: schema, TargetSchema: "db", - TablePattern: "t_2", + TablePattern: tb2, TargetTable: "T", }, }, @@ -378,9 +390,6 @@ func (s *testCheckerSuite) TestSameTargetTableDetection(c *tc.C) { }, } - schema := "db_1" - tb1 := "t_1" - tb2 := "t_2" createTable1 := `CREATE TABLE %s ( id int(11) NOT NULL AUTO_INCREMENT, b int(11) DEFAULT NULL, diff --git a/checker/checker.go b/checker/checker.go index bdd6c48ec5..035d230ea0 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -61,7 +61,7 @@ type mysqlInstance struct { targetDBInfo *dbutil.DBConfig } -// Checker performs pre-check of data synchronization +// Checker performs pre-check of data synchronization. type Checker struct { closed sync2.AtomicBool @@ -77,7 +77,7 @@ type Checker struct { } } -// NewChecker returns a checker +// NewChecker returns a checker. func NewChecker(cfgs []*config.SubTaskConfig, checkingItems map[string]string) *Checker { c := &Checker{ instances: make([]*mysqlInstance, 0, len(cfgs)), @@ -96,7 +96,7 @@ func NewChecker(cfgs []*config.SubTaskConfig, checkingItems map[string]string) * return c } -// Init implements Unit interface +// Init implements Unit interface. func (c *Checker) Init(ctx context.Context) (err error) { rollbackHolder := fr.NewRollbackHolder("checker") defer func() { @@ -246,7 +246,7 @@ func (c *Checker) displayCheckingItems() string { return buf.String() } -// Process implements Unit interface +// Process implements Unit interface. func (c *Checker) Process(ctx context.Context, pr chan pb.ProcessResult) { cctx, cancel := context.WithTimeout(ctx, checkTimeout) defer cancel() @@ -293,7 +293,7 @@ func (c *Checker) Process(ctx context.Context, pr chan pb.ProcessResult) { } } -// updateInstruction updates the check result's Instruction +// updateInstruction updates the check result's Instruction. func (c *Checker) updateInstruction(result *check.Results) { for _, r := range result.Results { if r.State == check.StateSuccess { @@ -301,8 +301,7 @@ func (c *Checker) updateInstruction(result *check.Results) { } // can't judge by other field, maybe update it later - switch r.Extra { - case check.AutoIncrementKeyChecking: + if r.Extra == check.AutoIncrementKeyChecking { if strings.HasPrefix(r.Instruction, "please handle it by yourself") { r.Instruction += ", refer to https://docs.pingcap.com/tidb-data-migration/stable/shard-merge-best-practices#handle-conflicts-of-auto-increment-primary-key) for details." } @@ -310,7 +309,7 @@ func (c *Checker) updateInstruction(result *check.Results) { } } -// Close implements Unit interface +// Close implements Unit interface. func (c *Checker) Close() { if c.closed.Get() { return @@ -339,7 +338,7 @@ func (c *Checker) closeDBs() { } } -// Pause implements Unit interface +// Pause implements Unit interface. func (c *Checker) Pause() { if c.closed.Get() { c.logger.Warn("try to pause, but already closed") @@ -347,7 +346,7 @@ func (c *Checker) Pause() { } } -// Resume resumes the paused process +// Resume resumes the paused process. func (c *Checker) Resume(ctx context.Context, pr chan pb.ProcessResult) { if c.closed.Get() { c.logger.Warn("try to resume, but already closed") @@ -357,23 +356,23 @@ func (c *Checker) Resume(ctx context.Context, pr chan pb.ProcessResult) { c.Process(ctx, pr) } -// Update implements Unit.Update +// Update implements Unit.Update. func (c *Checker) Update(cfg *config.SubTaskConfig) error { // not support update configuration now return nil } -// Type implements Unit interface +// Type implements Unit interface. func (c *Checker) Type() pb.UnitType { return pb.UnitType_Check } -// IsFreshTask implements Unit.IsFreshTask +// IsFreshTask implements Unit.IsFreshTask. func (c *Checker) IsFreshTask() (bool, error) { return true, nil } -// Status implements Unit interface +// Status implements Unit interface. func (c *Checker) Status() interface{} { c.result.RLock() res := c.result.detail @@ -394,7 +393,7 @@ func (c *Checker) Status() interface{} { } } -// Error implements Unit interface +// Error implements Unit interface. func (c *Checker) Error() interface{} { return &pb.CheckError{} } diff --git a/checker/cmd.go b/checker/cmd.go index 5b3733e4a0..af3703fdb1 100644 --- a/checker/cmd.go +++ b/checker/cmd.go @@ -25,7 +25,7 @@ var ( // ErrorMsgHeader used as the header of the error message when checking config failed. ErrorMsgHeader = "fail to check synchronization configuration with type" - // CheckSyncConfigFunc holds the CheckSyncConfig function + // CheckSyncConfigFunc holds the CheckSyncConfig function. CheckSyncConfigFunc func(ctx context.Context, cfgs []*config.SubTaskConfig) error ) @@ -33,7 +33,7 @@ func init() { CheckSyncConfigFunc = CheckSyncConfig } -// CheckSyncConfig checks synchronization configuration +// CheckSyncConfig checks synchronization configuration. func CheckSyncConfig(ctx context.Context, cfgs []*config.SubTaskConfig) error { if len(cfgs) == 0 { return nil @@ -58,8 +58,7 @@ func CheckSyncConfig(ctx context.Context, cfgs []*config.SubTaskConfig) error { c := NewChecker(cfgs, checkingItems) - err := c.Init(ctx) - if err != nil { + if err := c.Init(ctx); err != nil { return terror.Annotate(err, "fail to initial checker") } defer c.Close() diff --git a/cmd/dm-ctl/main.go b/cmd/dm-ctl/main.go index b651d525e9..bfc57a2072 100644 --- a/cmd/dm-ctl/main.go +++ b/cmd/dm-ctl/main.go @@ -36,16 +36,16 @@ import ( // output: // Usage: dmctl [global options] command [command options] [arguments...] // -//Available Commands: +// Available Commands: // ... // query-status query-status [-s source ...] [task-name] // ... // -//Special Commands: +// Special Commands: // --encrypt encrypt plaintext to ciphertext // ... // -//Global Options: +// Global Options: // --V prints version and exit // ... func helpUsage(cfg *common.Config) { @@ -87,7 +87,7 @@ func main() { Level: "info", }) if err != nil { - common.PrintLines("init logger error %s", terror.Message(err)) + common.PrintLinesf("init logger error %s", terror.Message(err)) os.Exit(2) } @@ -99,7 +99,7 @@ func main() { lenArgs := len(args) lenCmdArgs := len(cmdArgs) if lenCmdArgs > 0 { - lenArgs = lenArgs - lenCmdArgs + lenArgs -= lenCmdArgs } finished, err := cfg.Parse(args[:lenArgs]) @@ -119,19 +119,19 @@ func main() { } os.Exit(0) default: - common.PrintLines("parse cmd flags err: %s", terror.Message(err)) + common.PrintLinesf("parse cmd flags err: %s", terror.Message(err)) os.Exit(2) } err = cfg.Validate() if err != nil { - common.PrintLines("flags are not validate: %s", terror.Message(err)) + common.PrintLinesf("flags are not validate: %s", terror.Message(err)) os.Exit(2) } err = ctl.Init(cfg) if err != nil { - common.PrintLines("%v", terror.Message(err)) + common.PrintLinesf("%v", terror.Message(err)) os.Exit(2) } if lenCmdArgs > 0 { @@ -215,7 +215,6 @@ func loop() { if err != nil { panic(err) } - defer l.Close() for { line, err := l.Readline() @@ -230,6 +229,7 @@ func loop() { line = strings.TrimSpace(line) if line == "exit" { + l.Close() os.Exit(0) } else if line == "" { continue @@ -247,6 +247,7 @@ func loop() { fmt.Fprintln(os.Stderr, "sync log failed", syncErr) } } + l.Close() } func aliasArgs(args []string) []string { diff --git a/cmd/dm-ctl/main_test.go b/cmd/dm-ctl/main_test.go index b5d63be728..d544c3029d 100644 --- a/cmd/dm-ctl/main_test.go +++ b/cmd/dm-ctl/main_test.go @@ -21,7 +21,7 @@ import ( "testing" ) -func TestRunMain(t *testing.T) { +func TestRunMain(_ *testing.T) { var args []string for _, arg := range os.Args { switch { diff --git a/cmd/dm-master/main.go b/cmd/dm-master/main.go index 7b7bc61609..888ac5fa2a 100644 --- a/cmd/dm-master/main.go +++ b/cmd/dm-master/main.go @@ -41,7 +41,7 @@ func main() { case flag.ErrHelp: os.Exit(0) default: - common.PrintLines("parse cmd flags err: %s", terror.Message(err)) + common.PrintLinesf("parse cmd flags err: %s", terror.Message(err)) os.Exit(2) } @@ -52,7 +52,7 @@ func main() { Format: cfg.LogFormat, }) if err != nil { - common.PrintLines("init logger error %s", terror.Message(err)) + common.PrintLinesf("init logger error %s", terror.Message(err)) os.Exit(2) } @@ -89,8 +89,7 @@ func main() { log.L().Info("dm-master exit") // 7. flush log - syncErr := log.L().Sync() - if syncErr != nil { + if syncErr := log.L().Sync(); syncErr != nil { fmt.Fprintln(os.Stderr, "sync log failed", syncErr) os.Exit(1) } diff --git a/cmd/dm-master/main_test.go b/cmd/dm-master/main_test.go index 9a7aaa0133..95a45495c2 100644 --- a/cmd/dm-master/main_test.go +++ b/cmd/dm-master/main_test.go @@ -23,7 +23,7 @@ import ( "time" ) -func TestRunMain(t *testing.T) { +func TestRunMain(_ *testing.T) { fmt.Println("dm-master startup", time.Now()) var args []string for _, arg := range os.Args { diff --git a/cmd/dm-syncer/config.go b/cmd/dm-syncer/config.go index 029423fc1c..6b4fb97422 100644 --- a/cmd/dm-syncer/config.go +++ b/cmd/dm-syncer/config.go @@ -93,7 +93,7 @@ func (c *commonConfig) newConfigFromSyncerConfig(args []string) (*config.SubTask fs.IntVar(&cfg.Batch, "b", 100, "batch commit count") fs.StringVar(&cfg.StatusAddr, "status-addr", ":8271", "status addr") fs.StringVar(&cfg.Meta, "meta", "syncer.meta", "syncer meta info") - //fs.StringVar(&cfg.PersistentTableDir, "persistent-dir", "", "syncer history table structures persistent dir; set to non-empty string will choosing history table structure according to column length when constructing DML") + // fs.StringVar(&cfg.PersistentTableDir, "persistent-dir", "", "syncer history table structures persistent dir; set to non-empty string will choosing history table structure according to column length when constructing DML") fs.StringVar(&cfg.LogLevel, "L", "info", "log level: debug, info, warn, error, fatal") fs.StringVar(&cfg.LogFile, "log-file", "", "log file path") fs.StringVar(&cfg.LogFormat, "log-format", "text", `the format of the log, "text" or "json"`) @@ -123,8 +123,7 @@ func (c *commonConfig) newConfigFromSyncerConfig(args []string) (*config.SubTask } func (c *commonConfig) parse(args []string) (*config.SubTaskConfig, error) { - err := c.FlagSet.Parse(args) - if err != nil { + if err := c.FlagSet.Parse(args); err != nil { return nil, errors.Trace(err) } if c.printVersion { @@ -140,7 +139,6 @@ func (c *commonConfig) parse(args []string) (*config.SubTaskConfig, error) { } func (c *commonConfig) newSubTaskConfig(args []string) (*config.SubTaskConfig, error) { - cfg := &config.SubTaskConfig{} cfg.SetFlagSet(flag.NewFlagSet("dm-syncer", flag.ContinueOnError)) fs := cfg.GetFlagSet() @@ -157,7 +155,7 @@ func (c *commonConfig) newSubTaskConfig(args []string) (*config.SubTaskConfig, e fs.IntVar(&cfg.WorkerCount, "c", 16, "parallel worker count") fs.IntVar(&cfg.Batch, "b", 100, "batch commit count") fs.StringVar(&cfg.StatusAddr, "status-addr", ":8271", "status addr") - //fs.StringVar(&cfg.PersistentTableDir, "persistent-dir", "", "syncer history table structures persistent dir; set to non-empty string will choosing history table structure according to column length when constructing DML") + // fs.StringVar(&cfg.PersistentTableDir, "persistent-dir", "", "syncer history table structures persistent dir; set to non-empty string will choosing history table structure according to column length when constructing DML") fs.StringVar(&cfg.LogLevel, "L", "info", "log level: debug, info, warn, error, fatal") fs.StringVar(&cfg.LogFile, "log-file", "", "log file path") fs.StringVar(&cfg.LogFormat, "log-format", "text", `the format of the log, "text" or "json"`) @@ -171,8 +169,7 @@ func (c *commonConfig) newSubTaskConfig(args []string) (*config.SubTaskConfig, e cfg.ServerID = uint32(serverID) - err := cfg.Parse(args, false) - if err != nil { + if err := cfg.Parse(args, false); err != nil { return nil, errors.Trace(err) } @@ -197,7 +194,7 @@ func newCommonConfig() *commonConfig { fs.IntVar(&cfg.Batch, "b", 100, "batch commit count") fs.StringVar(&cfg.StatusAddr, "status-addr", ":8271", "status addr") fs.StringVar(&cfg.Meta, "meta", "syncer.meta", "syncer meta info") - //fs.StringVar(&cfg.PersistentTableDir, "persistent-dir", "", "syncer history table structures persistent dir; set to non-empty string will choosing history table structure according to column length when constructing DML") + // fs.StringVar(&cfg.PersistentTableDir, "persistent-dir", "", "syncer history table structures persistent dir; set to non-empty string will choosing history table structure according to column length when constructing DML") fs.StringVar(&cfg.LogLevel, "L", "info", "log level: debug, info, warn, error, fatal") fs.StringVar(&cfg.LogFile, "log-file", "", "log file path") fs.StringVar(&cfg.LogFormat, "log-format", "text", `the format of the log, "text" or "json"`) @@ -263,10 +260,10 @@ type syncerConfig struct { // NOTE: These four configs are all deprecated. // We leave this items as comments to remind others there WERE old config items. - //stopOnDDL bool `toml:"stop-on-ddl" json:"stop-on-ddl"` - //MaxDDLConnectionTimeout string `toml:"execute-ddl-timeout" json:"execute-ddl-timeout"` - //MaxDMLConnectionTimeout string `toml:"execute-dml-timeout" json:"execute-dml-timeout"` - //ExecutionQueueLength int `toml:"execute-queue-length" json:"execute-queue-length"` + // stopOnDDL bool `toml:"stop-on-ddl" json:"stop-on-ddl"` + // MaxDDLConnectionTimeout string `toml:"execute-ddl-timeout" json:"execute-ddl-timeout"` + // MaxDMLConnectionTimeout string `toml:"execute-dml-timeout" json:"execute-dml-timeout"` + // ExecutionQueueLength int `toml:"execute-queue-length" json:"execute-queue-length"` TimezoneStr string `toml:"timezone" json:"timezone"` Timezone *time.Location `json:"-"` @@ -276,7 +273,7 @@ type syncerConfig struct { // RouteRule is route rule that syncing // schema/table to specified schema/table -// This config has been replaced by `router.TableRule` +// This config has been replaced by `router.TableRule`. type RouteRule struct { PatternSchema string `toml:"pattern-schema" json:"pattern-schema"` PatternTable string `toml:"pattern-table" json:"pattern-table"` diff --git a/cmd/dm-syncer/main.go b/cmd/dm-syncer/main.go index 0748e80af4..5414e0d876 100644 --- a/cmd/dm-syncer/main.go +++ b/cmd/dm-syncer/main.go @@ -44,7 +44,7 @@ func main() { case flag.ErrHelp: os.Exit(0) default: - common.PrintLines("parse cmd flags err: %s", terror.Message(err)) + common.PrintLinesf("parse cmd flags err: %s", terror.Message(err)) os.Exit(2) } @@ -58,7 +58,7 @@ func main() { Level: strings.ToLower(conf.LogLevel), }) if err != nil { - common.PrintLines("init logger error %s", terror.Message(err)) + common.PrintLinesf("init logger error %s", terror.Message(err)) os.Exit(2) } @@ -106,8 +106,7 @@ func main() { log.L().Info("dm-syncer exit") // 6. flush log - syncErr := log.L().Sync() - if syncErr != nil { + if syncErr := log.L().Sync(); syncErr != nil { fmt.Fprintln(os.Stderr, "sync log failed", syncErr) os.Exit(1) } diff --git a/cmd/dm-syncer/main_test.go b/cmd/dm-syncer/main_test.go index 8103a5abb0..7d6a83b660 100644 --- a/cmd/dm-syncer/main_test.go +++ b/cmd/dm-syncer/main_test.go @@ -23,7 +23,7 @@ import ( "time" ) -func TestRunMain(t *testing.T) { +func TestRunMain(_ *testing.T) { fmt.Println("dm-syncer startup", time.Now()) var args []string for _, arg := range os.Args { diff --git a/cmd/dm-worker/main.go b/cmd/dm-worker/main.go index 1322c19b5f..febad78ed2 100644 --- a/cmd/dm-worker/main.go +++ b/cmd/dm-worker/main.go @@ -40,7 +40,7 @@ func main() { case flag.ErrHelp: os.Exit(0) default: - common.PrintLines("parse cmd flags err: %s", terror.Message(err)) + common.PrintLinesf("parse cmd flags err: %s", terror.Message(err)) os.Exit(2) } @@ -50,7 +50,7 @@ func main() { Level: strings.ToLower(cfg.LogLevel), }) if err != nil { - common.PrintLines("init logger error %s", terror.Message(err)) + common.PrintLinesf("init logger error %s", terror.Message(err)) os.Exit(2) } diff --git a/cmd/dm-worker/main_test.go b/cmd/dm-worker/main_test.go index e52e76c8c3..d5fa9cda5d 100644 --- a/cmd/dm-worker/main_test.go +++ b/cmd/dm-worker/main_test.go @@ -28,7 +28,7 @@ import ( "go.uber.org/zap" ) -func TestRunMain(t *testing.T) { +func TestRunMain(_ *testing.T) { fmt.Println("dm-worker startup", time.Now()) var ( args []string diff --git a/debug-tools/binlog-event-blackhole/fetcher.go b/debug-tools/binlog-event-blackhole/fetcher.go index 25bb7bf82c..baa9d3c7c6 100644 --- a/debug-tools/binlog-event-blackhole/fetcher.go +++ b/debug-tools/binlog-event-blackhole/fetcher.go @@ -105,7 +105,7 @@ func readEventsWithGoMySQL(ctx context.Context, conn *client.Conn) (uint64, uint log.L().Warn("receive EOF packet, retrying") continue default: - log.L().Warn("invalid stream header, retrying", zap.Uint8("header", uint8(data[0]))) + log.L().Warn("invalid stream header, retrying", zap.Uint8("header", data[0])) continue } } @@ -149,7 +149,7 @@ func readEventsWithoutGoMySQL(ctx context.Context, conn *client.Conn) (uint64, u } // readDataOnly reads the binary data only and does not parse packet or binlog event. -func readDataOnly(ctx context.Context, conn *client.Conn) (uint64, uint64, time.Duration, error) { +func readDataOnly(ctx context.Context, conn *client.Conn) (uint64, time.Duration, error) { var ( buf = make([]byte, 10240) byteCount sync2.AtomicUint64 @@ -158,13 +158,13 @@ func readDataOnly(ctx context.Context, conn *client.Conn) (uint64, uint64, time. for { select { case <-ctx.Done(): - return 0, byteCount.Get(), time.Since(startTime), nil + return byteCount.Get(), time.Since(startTime), nil default: } n, err := conn.Conn.Conn.Read(buf) if err != nil { - return 0, byteCount.Get(), time.Since(startTime), errors.Annotatef(err, "read binary data") + return byteCount.Get(), time.Since(startTime), errors.Annotatef(err, "read binary data") } byteCount.Add(uint64(n)) } diff --git a/debug-tools/binlog-event-blackhole/main.go b/debug-tools/binlog-event-blackhole/main.go index b4201951ff..97c36bb4ea 100644 --- a/debug-tools/binlog-event-blackhole/main.go +++ b/debug-tools/binlog-event-blackhole/main.go @@ -96,7 +96,7 @@ func main() { case 2: eventCount, byteCount, duration, err = readEventsWithoutGoMySQL(ctx, conn) case 3: - eventCount, byteCount, duration, err = readDataOnly(ctx, conn) + byteCount, duration, err = readDataOnly(ctx, conn) default: log.L().Error("invalid mode specified`", zap.Int("mode", cfg.mode)) } diff --git a/dm/common/common.go b/dm/common/common.go index 456aad4640..e8dde43435 100644 --- a/dm/common/common.go +++ b/dm/common/common.go @@ -25,15 +25,15 @@ import ( var ( useOfClosedErrMsg = "use of closed network connection" // ClusterVersionKey is used to store the version of the cluster. - ClusterVersionKey string = "/dm-cluster/version" + ClusterVersionKey = "/dm-cluster/version" // WorkerRegisterKeyAdapter is used to encode and decode register key. // k/v: Encode(worker-name) -> the information of the DM-worker node. WorkerRegisterKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-worker/r/") // WorkerKeepAliveKeyAdapter is used to encode and decode keepalive key. - // k/v: Encode(worker-name) -> time + // k/v: Encode(worker-name) -> time. WorkerKeepAliveKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-worker/a/") // UpstreamConfigKeyAdapter stores all config of which MySQL-task has not stopped. - // k/v: Encode(source-id) -> config + // k/v: Encode(source-id) -> config. UpstreamConfigKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/v2/upstream/config/") // UpstreamBoundWorkerKeyAdapter is used to store address of worker in which MySQL-tasks which are running. // k/v: Encode(worker-name) -> the bound relationship. @@ -43,13 +43,13 @@ var ( // k/v: Encode(worker-name) -> the bound relationship. UpstreamLastBoundWorkerKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/last-bound-worker/") // UpstreamRelayWorkerKeyAdapter is used to store the upstream which this worker needs to pull relay log - // k/v: Encode(worker-name) -> source-id + // k/v: Encode(worker-name) -> source-id. UpstreamRelayWorkerKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/relay-worker/") // TaskConfigKeyAdapter is used to store task config string. - // k/v: Encode(task-name) -> task-config-string + // k/v: Encode(task-name) -> task-config-string. TaskConfigKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/task/") // UpstreamSubTaskKeyAdapter is used to store SubTask which are subscribing data from MySQL source. - // k/v: Encode(source-id, task-name) -> SubTaskConfig + // k/v: Encode(source-id, task-name) -> SubTaskConfig. UpstreamSubTaskKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/upstream/subtask/") // StageRelayKeyAdapter is used to store the running stage of the relay. // k/v: Encode(source-id) -> the running stage of the relay. @@ -59,10 +59,10 @@ var ( StageSubTaskKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/stage/subtask/") // ShardDDLPessimismInfoKeyAdapter is used to store shard DDL info in pessimistic model. - // k/v: Encode(task-name, source-id) -> shard DDL info + // k/v: Encode(task-name, source-id) -> shard DDL info. ShardDDLPessimismInfoKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/shardddl-pessimism/info/") // ShardDDLPessimismOperationKeyAdapter is used to store shard DDL operation in pessimistic model. - // k/v: Encode(task-name, source-id) -> shard DDL operation + // k/v: Encode(task-name, source-id) -> shard DDL operation. ShardDDLPessimismOperationKeyAdapter KeyAdapter = keyHexEncoderDecoder("/dm-master/shardddl-pessimism/operation/") // ShardDDLOptimismSourceTablesKeyAdapter is used to store INITIAL upstream schema & table names when starting the subtask. @@ -113,7 +113,7 @@ func keyAdapterKeysLen(s KeyAdapter) int { return -1 } -// IsErrNetClosing checks whether is an ErrNetClosing error +// IsErrNetClosing checks whether is an ErrNetClosing error. func IsErrNetClosing(err error) bool { if err == nil { return false @@ -134,7 +134,7 @@ type KeyAdapter interface { type keyEncoderDecoder string -// always use keyHexEncoderDecoder to avoid `/` in keys +// always use keyHexEncoderDecoder to avoid `/` in keys. type keyHexEncoderDecoder string func (s keyEncoderDecoder) Encode(keys ...string) string { @@ -190,10 +190,10 @@ func (s keyHexEncoderDecoder) Path() string { return string(s) } -// used in upgrade +// used in upgrade. var ( // UpstreamConfigKeyAdapter stores all config of which MySQL-task has not stopped. - // k/v: Encode(source-id) -> config + // k/v: Encode(source-id) -> config. UpstreamConfigKeyAdapterV1 KeyAdapter = keyEncoderDecoder("/dm-master/upstream/config/") // StageRelayKeyAdapter is used to store the running stage of the relay. // k/v: Encode(source-id) -> the running stage of the relay. diff --git a/dm/config/checker_config.go b/dm/config/checker_config.go index 3d6322f886..0b3e961190 100644 --- a/dm/config/checker_config.go +++ b/dm/config/checker_config.go @@ -5,7 +5,7 @@ import ( "time" ) -// Backoff related constants +// Backoff related constants. var ( DefaultCheckInterval = 5 * time.Second DefaultBackoffRollback = 5 * time.Minute @@ -15,26 +15,26 @@ var ( DefaultBackoffFactor float64 = 2 ) -// Duration is used to hold a time.Duration field +// Duration is used to hold a time.Duration field. type Duration struct { time.Duration } // MarshalText hacks to satisfy the encoding.TextMarshaler interface -// For MarshalText, we should use (d Duration) which can be used by both pointer and instance +// For MarshalText, we should use (d Duration) which can be used by both pointer and instance. func (d Duration) MarshalText() ([]byte, error) { return []byte(d.Duration.String()), nil } // UnmarshalText hacks to satisfy the encoding.TextUnmarshaler interface -// For UnmarshalText, we should use (d *Duration) to change the value of this instance instead of the copy +// For UnmarshalText, we should use (d *Duration) to change the value of this instance instead of the copy. func (d *Duration) UnmarshalText(text []byte) error { var err error d.Duration, err = time.ParseDuration(string(text)) return err } -// MarshalJSON hacks to satisfy the json.Marshaler interface +// MarshalJSON hacks to satisfy the json.Marshaler interface. func (d *Duration) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { Duration string `json:"Duration"` @@ -43,7 +43,7 @@ func (d *Duration) MarshalJSON() ([]byte, error) { }) } -// CheckerConfig is configuration used for TaskStatusChecker +// CheckerConfig is configuration used for TaskStatusChecker. type CheckerConfig struct { CheckEnable bool `yaml:"check-enable" toml:"check-enable" json:"check-enable"` BackoffRollback Duration `yaml:"backoff-rollback" toml:"backoff-rollback" json:"backoff-rollback"` @@ -55,7 +55,7 @@ type CheckerConfig struct { BackoffFactor float64 `yaml:"backoff-factor" toml:"backoff-factor" json:"-"` } -// Adjust sets default value for field: CheckInterval/BackoffMin/BackoffJitter/BackoffFactor +// Adjust sets default value for field: CheckInterval/BackoffMin/BackoffJitter/BackoffFactor. func (cc *CheckerConfig) Adjust() { cc.CheckInterval = Duration{Duration: DefaultCheckInterval} cc.BackoffMin = Duration{Duration: DefaultBackoffMin} diff --git a/dm/config/checking_item.go b/dm/config/checking_item.go index d8a7f6259f..cedac3bee4 100644 --- a/dm/config/checking_item.go +++ b/dm/config/checking_item.go @@ -21,7 +21,7 @@ import ( ) // DM definition checking items -// refer github.com/pingcap/tidb-tools/pkg/check +// refer github.com/pingcap/tidb-tools/pkg/check. const ( AllChecking = "all" DumpPrivilegeChecking = "dump_privilege" @@ -36,7 +36,7 @@ const ( ShardAutoIncrementIDChecking = "auto_increment_ID" ) -// AllCheckingItems contains all checking items +// AllCheckingItems contains all checking items. var AllCheckingItems = map[string]string{ AllChecking: "all checking items", DumpPrivilegeChecking: "dump privileges of source DB checking item", @@ -51,10 +51,10 @@ var AllCheckingItems = map[string]string{ ShardAutoIncrementIDChecking: "conflict auto increment ID of shard tables checking item", } -// MaxSourceIDLength is the max length for dm-worker source id +// MaxSourceIDLength is the max length for dm-worker source id. const MaxSourceIDLength = 32 -// ValidateCheckingItem validates checking item +// ValidateCheckingItem validates checking item. func ValidateCheckingItem(item string) error { if _, ok := AllCheckingItems[item]; ok { return nil @@ -63,7 +63,7 @@ func ValidateCheckingItem(item string) error { return terror.ErrConfigCheckItemNotSupport.Generate(item, SupportCheckingItems()) } -// SupportCheckingItems returns all supporting checking item +// SupportCheckingItems returns all supporting checking item. func SupportCheckingItems() string { var buf bytes.Buffer fmt.Fprintf(&buf, "************ supporting checking items ************\n name:\t\tdescription\n") @@ -74,7 +74,7 @@ func SupportCheckingItems() string { return buf.String() } -// FilterCheckingItems filters ignored items from all checking items +// FilterCheckingItems filters ignored items from all checking items. func FilterCheckingItems(ignoredItems []string) map[string]string { checkingItems := make(map[string]string) for item, desc := range AllCheckingItems { diff --git a/dm/config/security.go b/dm/config/security.go index 08dd4cd65a..5d8eb994aa 100644 --- a/dm/config/security.go +++ b/dm/config/security.go @@ -15,7 +15,7 @@ package config import "fmt" -// Security config +// Security config. type Security struct { SSLCA string `toml:"ssl-ca" json:"ssl-ca" yaml:"ssl-ca"` SSLCert string `toml:"ssl-cert" json:"ssl-cert" yaml:"ssl-cert"` @@ -23,7 +23,7 @@ type Security struct { CertAllowedCN strArray `toml:"cert-allowed-cn" json:"cert-allowed-cn" yaml:"cert-allowed-cn"` } -// used for parse string slice in flag +// used for parse string slice in flag. type strArray []string func (i *strArray) String() string { diff --git a/dm/config/source_config.go b/dm/config/source_config.go index 93559a2bf3..8b4d4891d3 100644 --- a/dm/config/source_config.go +++ b/dm/config/source_config.go @@ -16,16 +16,17 @@ import ( "github.com/siddontang/go-mysql/mysql" "gopkg.in/yaml.v2" + bf "github.com/pingcap/tidb-tools/pkg/binlog-filter" + "github.com/pingcap/dm/pkg/binlog" "github.com/pingcap/dm/pkg/gtid" "github.com/pingcap/dm/pkg/log" "github.com/pingcap/dm/pkg/terror" "github.com/pingcap/dm/pkg/utils" - bf "github.com/pingcap/tidb-tools/pkg/binlog-filter" ) const ( - // the default base(min) server id generated by random + // the default base(min) server id generated by random. defaultBaseServerID = math.MaxUint32 / 10 defaultRelayDir = "relay-dir" ) @@ -34,17 +35,17 @@ var getAllServerIDFunc = utils.GetAllServerID // SampleConfigFile is sample config file of source // later we can read it from dm/master/source.yaml -// and assign it to SampleConfigFile while we build dm-ctl +// and assign it to SampleConfigFile while we build dm-ctl. var SampleConfigFile string -// PurgeConfig is the configuration for Purger +// PurgeConfig is the configuration for Purger. type PurgeConfig struct { Interval int64 `yaml:"interval" toml:"interval" json:"interval"` // check whether need to purge at this @Interval (seconds) Expires int64 `yaml:"expires" toml:"expires" json:"expires"` // if file's modified time is older than @Expires (hours), then it can be purged RemainSpace int64 `yaml:"remain-space" toml:"remain-space" json:"remain-space"` // if remain space in @RelayBaseDir less than @RemainSpace (GB), then it can be purged } -// SourceConfig is the configuration for Worker +// SourceConfig is the configuration for Worker. type SourceConfig struct { EnableGTID bool `yaml:"enable-gtid" toml:"enable-gtid" json:"enable-gtid"` AutoFixGTID bool `yaml:"auto-fix-gtid" toml:"auto-fix-gtid" json:"auto-fix-gtid"` @@ -97,14 +98,14 @@ func NewSourceConfig() *SourceConfig { return c } -// Clone clones a config +// Clone clones a config. func (c *SourceConfig) Clone() *SourceConfig { clone := &SourceConfig{} *clone = *c return clone } -// Toml returns TOML format representation of config +// Toml returns TOML format representation of config. func (c *SourceConfig) Toml() (string, error) { var b bytes.Buffer @@ -116,7 +117,7 @@ func (c *SourceConfig) Toml() (string, error) { return b.String(), nil } -// Yaml returns YAML format representation of config +// Yaml returns YAML format representation of config. func (c *SourceConfig) Yaml() (string, error) { b, err := yaml.Marshal(c) if err != nil { @@ -127,7 +128,7 @@ func (c *SourceConfig) Yaml() (string, error) { } // Parse parses flag definitions from the argument list. -// accept toml content for legacy use (mainly used by etcd) +// accept toml content for legacy use (mainly used by etcd). func (c *SourceConfig) Parse(content string) error { // Parse first to get config file. metaData, err := toml.Decode(content, c) @@ -138,7 +139,7 @@ func (c *SourceConfig) Parse(content string) error { return c.Verify() } -// ParseYaml parses flag definitions from the argument list, content should be yaml format +// ParseYaml parses flag definitions from the argument list, content should be yaml format. func (c *SourceConfig) ParseYaml(content string) error { if err := yaml.UnmarshalStrict([]byte(content), c); err != nil { return terror.ErrConfigYamlTransform.Delegate(err, "decode source config") @@ -169,7 +170,7 @@ func (c *SourceConfig) adjust() { c.Checker.Adjust() } -// Verify verifies the config +// Verify verifies the config. func (c *SourceConfig) Verify() error { if len(c.SourceID) == 0 { return terror.ErrWorkerNeedSourceID.Generate() @@ -201,12 +202,10 @@ func (c *SourceConfig) Verify() error { return nil } -// DecryptPassword returns a decrypted config replica in config +// DecryptPassword returns a decrypted config replica in config. func (c *SourceConfig) DecryptPassword() *SourceConfig { clone := c.Clone() - var ( - pswdFrom string - ) + var pswdFrom string if len(clone.From.Password) > 0 { pswdFrom = utils.DecryptOrPlaintext(clone.From.Password) } @@ -214,7 +213,7 @@ func (c *SourceConfig) DecryptPassword() *SourceConfig { return clone } -// GenerateDBConfig creates DBConfig for DB +// GenerateDBConfig creates DBConfig for DB. func (c *SourceConfig) GenerateDBConfig() *DBConfig { // decrypt password clone := c.DecryptPassword() @@ -223,7 +222,7 @@ func (c *SourceConfig) GenerateDBConfig() *DBConfig { return from } -// Adjust flavor and server-id of SourceConfig +// Adjust flavor and server-id of SourceConfig. func (c *SourceConfig) Adjust(ctx context.Context, db *sql.DB) (err error) { c.From.Adjust() c.Checker.Adjust() @@ -264,7 +263,7 @@ func (c *SourceConfig) Adjust(ctx context.Context, db *sql.DB) (err error) { return nil } -// AdjustFlavor adjust Flavor from DB +// AdjustFlavor adjust Flavor from DB. func (c *SourceConfig) AdjustFlavor(ctx context.Context, db *sql.DB) (err error) { if c.Flavor != "" { switch c.Flavor { @@ -282,7 +281,7 @@ func (c *SourceConfig) AdjustFlavor(ctx context.Context, db *sql.DB) (err error) return terror.WithScope(err, terror.ScopeUpstream) } -// AdjustServerID adjust server id from DB +// AdjustServerID adjust server id from DB. func (c *SourceConfig) AdjustServerID(ctx context.Context, db *sql.DB) error { if c.ServerID != 0 { return nil diff --git a/dm/config/source_config_test.go b/dm/config/source_config_test.go index ca83372888..7d3932aab8 100644 --- a/dm/config/source_config_test.go +++ b/dm/config/source_config_test.go @@ -114,7 +114,7 @@ func (t *testConfig) TestConfig(c *C) { source-id: haha aaa: xxx `) - err = ioutil.WriteFile(configFile, configContent, 0644) + err = ioutil.WriteFile(configFile, configContent, 0o644) c.Assert(err, IsNil) err = cfg.LoadFromFile(configFile) c.Assert(err, NotNil) @@ -226,7 +226,6 @@ func (t *testConfig) TestConfigVerify(c *C) { c.Assert(err, IsNil) } } - } func subtestFlavor(c *C, cfg *SourceConfig, sqlInfo, expectedFlavor, expectedError string) { @@ -265,7 +264,7 @@ func (t *testConfig) TestAdjustFlavor(c *C) { } func (t *testConfig) TestAdjustServerID(c *C) { - var originGetAllServerIDFunc = getAllServerIDFunc + originGetAllServerIDFunc := getAllServerIDFunc defer func() { getAllServerIDFunc = originGetAllServerIDFunc }() diff --git a/dm/config/subtask.go b/dm/config/subtask.go index b3c5a70f69..d534b83c85 100644 --- a/dm/config/subtask.go +++ b/dm/config/subtask.go @@ -33,38 +33,36 @@ import ( "go.uber.org/zap" ) -// task modes +// task modes. const ( ModeAll = "all" ModeFull = "full" ModeIncrement = "incremental" ) -var ( - defaultMaxIdleConns = 2 -) +var defaultMaxIdleConns = 2 -// RawDBConfig contains some low level database config +// RawDBConfig contains some low level database config. type RawDBConfig struct { MaxIdleConns int ReadTimeout string WriteTimeout string } -// DefaultRawDBConfig returns a default raw database config +// DefaultRawDBConfig returns a default raw database config. func DefaultRawDBConfig() *RawDBConfig { return &RawDBConfig{ MaxIdleConns: defaultMaxIdleConns, } } -// SetReadTimeout set readTimeout for raw database config +// SetReadTimeout set readTimeout for raw database config. func (c *RawDBConfig) SetReadTimeout(readTimeout string) *RawDBConfig { c.ReadTimeout = readTimeout return c } -// SetWriteTimeout set writeTimeout for raw database config +// SetWriteTimeout set writeTimeout for raw database config. func (c *RawDBConfig) SetWriteTimeout(writeTimeout string) *RawDBConfig { c.WriteTimeout = writeTimeout return c @@ -102,18 +100,17 @@ func (db *DBConfig) String() string { return string(cfg) } -// Toml returns TOML format representation of config +// Toml returns TOML format representation of config. func (db *DBConfig) Toml() (string, error) { var b bytes.Buffer enc := toml.NewEncoder(&b) - err := enc.Encode(db) - if err != nil { + if err := enc.Encode(db); err != nil { return "", terror.ErrConfigTomlTransform.Delegate(err, "encode db config to toml") } return b.String(), nil } -// Decode loads config from file data +// Decode loads config from file data. func (db *DBConfig) Decode(data string) error { _, err := toml.Decode(data, db) return terror.ErrConfigTomlTransform.Delegate(err, "decode db config") @@ -123,7 +120,7 @@ func (db *DBConfig) Decode(data string) error { func (db *DBConfig) Adjust() { } -// SubTaskConfig is the configuration for SubTask +// SubTaskConfig is the configuration for SubTask. type SubTaskConfig struct { // BurntSushi/toml seems have a bug for flag "-" // when doing encoding, if we use `toml:"-"`, it still try to encode it @@ -195,7 +192,7 @@ type SubTaskConfig struct { printVersion bool } -// NewSubTaskConfig creates a new SubTaskConfig +// NewSubTaskConfig creates a new SubTaskConfig. func NewSubTaskConfig() *SubTaskConfig { cfg := &SubTaskConfig{} return cfg @@ -211,7 +208,7 @@ func (c *SubTaskConfig) SetFlagSet(flagSet *flag.FlagSet) { c.flagSet = flagSet } -// String returns the config's json string +// String returns the config's json string. func (c *SubTaskConfig) String() string { cfg, err := json.Marshal(c) if err != nil { @@ -220,18 +217,17 @@ func (c *SubTaskConfig) String() string { return string(cfg) } -// Toml returns TOML format representation of config +// Toml returns TOML format representation of config. func (c *SubTaskConfig) Toml() (string, error) { var b bytes.Buffer enc := toml.NewEncoder(&b) - err := enc.Encode(c) - if err != nil { + if err := enc.Encode(c); err != nil { return "", terror.ErrConfigTomlTransform.Delegate(err, "encode subtask config") } return b.String(), nil } -// DecodeFile loads and decodes config from file +// DecodeFile loads and decodes config from file. func (c *SubTaskConfig) DecodeFile(fpath string, verifyDecryptPassword bool) error { _, err := toml.DecodeFile(fpath, c) if err != nil { @@ -241,17 +237,16 @@ func (c *SubTaskConfig) DecodeFile(fpath string, verifyDecryptPassword bool) err return c.Adjust(verifyDecryptPassword) } -// Decode loads config from file data +// Decode loads config from file data. func (c *SubTaskConfig) Decode(data string, verifyDecryptPassword bool) error { - _, err := toml.Decode(data, c) - if err != nil { + if _, err := toml.Decode(data, c); err != nil { return terror.ErrConfigTomlTransform.Delegate(err, "decode subtask config from data") } return c.Adjust(verifyDecryptPassword) } -// Adjust adjusts configs +// Adjust adjusts configs. func (c *SubTaskConfig) Adjust(verifyDecryptPassword bool) error { if c.Name == "" { return terror.ErrConfigTaskNameEmpty.Generate() @@ -264,10 +259,6 @@ func (c *SubTaskConfig) Adjust(verifyDecryptPassword bool) error { return terror.ErrConfigTooLongSourceID.Generate() } - //if c.Flavor != mysql.MySQLFlavor && c.Flavor != mysql.MariaDBFlavor { - // return errors.Errorf("please specify right mysql version, support mysql, mariadb now") - //} - if c.ShardMode != "" && c.ShardMode != ShardPessimistic && c.ShardMode != ShardOptimistic { return terror.ErrConfigShardModeNotSupport.Generate(c.ShardMode) } else if c.ShardMode == "" && c.IsSharding { @@ -354,7 +345,7 @@ func (c *SubTaskConfig) Parse(arguments []string, verifyDecryptPassword bool) er return c.Adjust(verifyDecryptPassword) } -// DecryptPassword tries to decrypt db password in config +// DecryptPassword tries to decrypt db password in config. func (c *SubTaskConfig) DecryptPassword() (*SubTaskConfig, error) { clone, err := c.Clone() if err != nil { @@ -377,7 +368,7 @@ func (c *SubTaskConfig) DecryptPassword() (*SubTaskConfig, error) { return clone, nil } -// Clone returns a replica of SubTaskConfig +// Clone returns a replica of SubTaskConfig. func (c *SubTaskConfig) Clone() (*SubTaskConfig, error) { content, err := c.Toml() if err != nil { diff --git a/dm/config/task.go b/dm/config/task.go index a033572b05..99af958b70 100644 --- a/dm/config/task.go +++ b/dm/config/task.go @@ -36,7 +36,7 @@ import ( yaml "gopkg.in/yaml.v2" ) -// Online DDL Scheme +// Online DDL Scheme. const ( GHOST = "gh-ost" PT = "pt" @@ -50,29 +50,29 @@ const ( tidbTxnOptimistic = "optimistic" ) -// default config item values +// default config item values. var ( - // TaskConfig + // TaskConfig. defaultMetaSchema = "dm_meta" defaultEnableHeartbeat = false defaultIsSharding = false defaultUpdateInterval = 1 defaultReportInterval = 10 - // MydumperConfig + // MydumperConfig. defaultMydumperPath = "./bin/mydumper" defaultThreads = 4 defaultChunkFilesize = "64" defaultSkipTzUTC = true - // LoaderConfig + // LoaderConfig. defaultPoolSize = 16 defaultDir = "./dumped_data" - // SyncerConfig + // SyncerConfig. defaultWorkerCount = 16 defaultBatch = 100 defaultQueueSize = 1024 // do not give too large default value to avoid OOM defaultCheckpointFlushInterval = 30 // in seconds - // TargetDBConfig + // TargetDBConfig. defaultSessionCfg = []struct { key string val string @@ -84,7 +84,7 @@ var ( // Meta represents binlog's meta pos // NOTE: refine to put these config structs into pkgs -// NOTE: now, syncer does not support GTID mode and which is supported by relay +// NOTE: now, syncer does not support GTID mode and which is supported by relay. type Meta struct { BinLogName string `toml:"binlog-name" yaml:"binlog-name"` BinLogPos uint32 `toml:"binlog-pos" yaml:"binlog-pos"` @@ -101,7 +101,7 @@ func (m *Meta) Verify() error { return nil } -// MySQLInstance represents a sync config of a MySQL instance +// MySQLInstance represents a sync config of a MySQL instance. type MySQLInstance struct { // it represents a MySQL/MariaDB instance or a replica group SourceID string `yaml:"source-id"` @@ -130,7 +130,7 @@ type MySQLInstance struct { SyncerThread int `yaml:"syncer-thread"` } -// VerifyAndAdjust does verification on configs, and adjust some configs +// VerifyAndAdjust does verification on configs, and adjust some configs. func (m *MySQLInstance) VerifyAndAdjust() error { if m == nil { return terror.ErrConfigMySQLInstNotFound.Generate() @@ -161,7 +161,7 @@ func (m *MySQLInstance) VerifyAndAdjust() error { return nil } -// MydumperConfig represents mydumper process unit's specific config +// MydumperConfig represents mydumper process unit's specific config. type MydumperConfig struct { MydumperPath string `yaml:"mydumper-path" toml:"mydumper-path" json:"mydumper-path"` // mydumper binary path Threads int `yaml:"threads" toml:"threads" json:"threads"` // -t, --threads @@ -185,10 +185,10 @@ func defaultMydumperConfig() MydumperConfig { } } -// alias to avoid infinite recursion for UnmarshalYAML +// alias to avoid infinite recursion for UnmarshalYAML. type rawMydumperConfig MydumperConfig -// UnmarshalYAML implements Unmarshaler.UnmarshalYAML +// UnmarshalYAML implements Unmarshaler.UnmarshalYAML. func (m *MydumperConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { raw := rawMydumperConfig(defaultMydumperConfig()) if err := unmarshal(&raw); err != nil { @@ -198,7 +198,7 @@ func (m *MydumperConfig) UnmarshalYAML(unmarshal func(interface{}) error) error return nil } -// LoaderConfig represents loader process unit's specific config +// LoaderConfig represents loader process unit's specific config. type LoaderConfig struct { PoolSize int `yaml:"pool-size" toml:"pool-size" json:"pool-size"` Dir string `yaml:"dir" toml:"dir" json:"dir"` @@ -212,10 +212,10 @@ func defaultLoaderConfig() LoaderConfig { } } -// alias to avoid infinite recursion for UnmarshalYAML +// alias to avoid infinite recursion for UnmarshalYAML. type rawLoaderConfig LoaderConfig -// UnmarshalYAML implements Unmarshaler.UnmarshalYAML +// UnmarshalYAML implements Unmarshaler.UnmarshalYAML. func (m *LoaderConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { raw := rawLoaderConfig(defaultLoaderConfig()) if err := unmarshal(&raw); err != nil { @@ -225,7 +225,7 @@ func (m *LoaderConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } -// SyncerConfig represents syncer process unit's specific config +// SyncerConfig represents syncer process unit's specific config. type SyncerConfig struct { MetaFile string `yaml:"meta-file" toml:"meta-file" json:"meta-file"` // meta filename, used only when load SubConfig directly WorkerCount int `yaml:"worker-count" toml:"worker-count" json:"worker-count"` @@ -255,10 +255,10 @@ func defaultSyncerConfig() SyncerConfig { } } -// alias to avoid infinite recursion for UnmarshalYAML +// alias to avoid infinite recursion for UnmarshalYAML. type rawSyncerConfig SyncerConfig -// UnmarshalYAML implements Unmarshaler.UnmarshalYAML +// UnmarshalYAML implements Unmarshaler.UnmarshalYAML. func (m *SyncerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { raw := rawSyncerConfig(defaultSyncerConfig()) if err := unmarshal(&raw); err != nil { @@ -268,7 +268,7 @@ func (m *SyncerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } -// TaskConfig is the configuration for Task +// TaskConfig is the configuration for Task. type TaskConfig struct { *flag.FlagSet `yaml:"-" toml:"-" json:"-"` @@ -317,7 +317,7 @@ type TaskConfig struct { RemoveMeta bool `yaml:"remove-meta"` } -// NewTaskConfig creates a TaskConfig +// NewTaskConfig creates a TaskConfig. func NewTaskConfig() *TaskConfig { cfg := &TaskConfig{ // explicitly set default value @@ -341,7 +341,7 @@ func NewTaskConfig() *TaskConfig { return cfg } -// String returns the config's yaml string +// String returns the config's yaml string. func (c *TaskConfig) String() string { cfg, err := yaml.Marshal(c) if err != nil { @@ -350,7 +350,7 @@ func (c *TaskConfig) String() string { return string(cfg) } -// JSON returns the config's json string +// JSON returns the config's json string. func (c *TaskConfig) JSON() string { //nolint:staticcheck cfg, err := json.Marshal(c) @@ -360,7 +360,7 @@ func (c *TaskConfig) JSON() string { return string(cfg) } -// DecodeFile loads and decodes config from file +// DecodeFile loads and decodes config from file. func (c *TaskConfig) DecodeFile(fpath string) error { bs, err := ioutil.ReadFile(fpath) if err != nil { @@ -375,7 +375,7 @@ func (c *TaskConfig) DecodeFile(fpath string) error { return c.adjust() } -// Decode loads config from file data +// Decode loads config from file data. func (c *TaskConfig) Decode(data string) error { err := yaml.UnmarshalStrict([]byte(data), c) if err != nil { @@ -385,7 +385,7 @@ func (c *TaskConfig) Decode(data string) error { return c.adjust() } -// adjust adjusts configs +// adjust adjusts configs. func (c *TaskConfig) adjust() error { if len(c.Name) == 0 { return terror.ErrConfigNeedUniqueTaskName.Generate() @@ -608,7 +608,7 @@ func (c *TaskConfig) adjust() error { return nil } -// SubTaskConfigs generates sub task configs +// SubTaskConfigs generates sub task configs. func (c *TaskConfig) SubTaskConfigs(sources map[string]DBConfig) ([]*SubTaskConfig, error) { cfgs := make([]*SubTaskConfig, len(c.MySQLInstances)) for i, inst := range c.MySQLInstances { @@ -680,7 +680,7 @@ func (c *TaskConfig) SubTaskConfigs(sources map[string]DBConfig) ([]*SubTaskConf // getGenerateName generates name by rule or gets name from nameMap // if it's a new name, increase nameIdx -// otherwise return current nameIdx +// otherwise return current nameIdx. func getGenerateName(rule interface{}, nameIdx int, namePrefix string, nameMap map[string]string) (string, int) { // use json as key since no DeepEqual for rules now. ruleByte, err := json.Marshal(rule) @@ -786,7 +786,7 @@ func FromSubTaskConfigs(stCfgs ...*SubTaskConfig) *TaskConfig { } // checkDuplicateString checks whether the given string array has duplicate string item -// if there is duplicate, it will return **all** the duplicate strings +// if there is duplicate, it will return **all** the duplicate strings. func checkDuplicateString(ruleNames []string) []string { mp := make(map[string]bool, len(ruleNames)) dupeArray := make([]string, 0) @@ -803,7 +803,7 @@ func checkDuplicateString(ruleNames []string) []string { return dupeArray } -// AdjustTargetDBSessionCfg adjust session cfg of TiDB +// AdjustTargetDBSessionCfg adjust session cfg of TiDB. func AdjustTargetDBSessionCfg(dbConfig *DBConfig, version *semver.Version) { lowerMap := make(map[string]string, len(dbConfig.Session)) for k, v := range dbConfig.Session { diff --git a/dm/config/task_test.go b/dm/config/task_test.go index 67218ecaf1..9fe4a4b6bb 100644 --- a/dm/config/task_test.go +++ b/dm/config/task_test.go @@ -20,16 +20,17 @@ import ( "strings" . "github.com/pingcap/check" - "github.com/pingcap/dm/pkg/terror" bf "github.com/pingcap/tidb-tools/pkg/binlog-filter" "github.com/pingcap/tidb-tools/pkg/filter" router "github.com/pingcap/tidb-tools/pkg/table-router" + "github.com/pingcap/dm/pkg/terror" + "github.com/coreos/go-semver/semver" ) func (t *testConfig) TestUnusedTaskConfig(c *C) { - var correctTaskConfig = `--- + correctTaskConfig := `--- name: test task-mode: all shard-mode: "pessimistic" @@ -131,7 +132,7 @@ mysql-instances: taskConfig := NewTaskConfig() err := taskConfig.Decode(correctTaskConfig) c.Assert(err, IsNil) - var errorTaskConfig = `--- + errorTaskConfig := `--- name: test task-mode: all shard-mode: "pessimistic" @@ -238,7 +239,7 @@ mysql-instances: } func (t *testConfig) TestInvalidTaskConfig(c *C) { - var errorTaskConfig1 = `--- + errorTaskConfig1 := `--- name: test task-mode: all is-sharding: true @@ -263,7 +264,7 @@ mysql-instances: loader-config-name: "global" syncer-config-name: "global" ` - var errorTaskConfig2 = `--- + errorTaskConfig2 := `--- name: test name: test1 task-mode: all @@ -310,7 +311,7 @@ enable-heartbeat: true timezone: "Asia/Shanghai" ignore-checking-items: ["all"] `) - err = ioutil.WriteFile(filepath, configContent, 0644) + err = ioutil.WriteFile(filepath, configContent, 0o644) c.Assert(err, IsNil) taskConfig = NewTaskConfig() err = taskConfig.DecodeFile(filepath) @@ -327,7 +328,7 @@ enable-heartbeat: true timezone: "Asia/Shanghai" ignore-checking-items: ["all"] `) - err = ioutil.WriteFile(filepath, configContent, 0644) + err = ioutil.WriteFile(filepath, configContent, 0o644) c.Assert(err, IsNil) taskConfig = NewTaskConfig() err = taskConfig.DecodeFile(filepath) @@ -342,7 +343,7 @@ enable-heartbeat: true timezone: "Asia/Shanghai" ignore-checking-items: ["all"] `) - err = ioutil.WriteFile(filepath, configContent, 0644) + err = ioutil.WriteFile(filepath, configContent, 0o644) c.Assert(err, IsNil) taskConfig = NewTaskConfig() err = taskConfig.DecodeFile(filepath) @@ -409,7 +410,7 @@ syncers: batch: 100 `) - err = ioutil.WriteFile(filepath, configContent, 0644) + err = ioutil.WriteFile(filepath, configContent, 0o644) c.Assert(err, IsNil) taskConfig = NewTaskConfig() err = taskConfig.DecodeFile(filepath) @@ -465,7 +466,7 @@ filters: filter-rule-4: `) - err = ioutil.WriteFile(filepath, configContent, 0644) + err = ioutil.WriteFile(filepath, configContent, 0o644) c.Assert(err, IsNil) taskConfig = NewTaskConfig() err = taskConfig.DecodeFile(filepath) @@ -478,7 +479,6 @@ filters: c.Assert(terror.ErrConfigDuplicateCfgItem.Equal(err), IsTrue) c.Assert(err, ErrorMatches, `[\s\S]*mysql-instance\(0\)'s route-rules: route-rule-1, route-rule-2[\s\S]*`) c.Assert(err, ErrorMatches, `[\s\S]*mysql-instance\(1\)'s filter-rules: filter-rule-2[\s\S]*`) - } func (t *testConfig) TestCheckDuplicateString(c *C) { @@ -851,6 +851,7 @@ func (t *testConfig) TestMetaVerify(c *C) { func (t *testConfig) TestMySQLInstance(c *C) { var m *MySQLInstance + cfgName := "test" err := m.VerifyAndAdjust() c.Assert(terror.ErrConfigMySQLInstNotFound.Equal(err), IsTrue) @@ -860,25 +861,24 @@ func (t *testConfig) TestMySQLInstance(c *C) { m.SourceID = "123" m.Mydumper = &MydumperConfig{} - m.MydumperConfigName = "test" + m.MydumperConfigName = cfgName err = m.VerifyAndAdjust() c.Assert(terror.ErrConfigMydumperCfgConflict.Equal(err), IsTrue) m.MydumperConfigName = "" m.Loader = &LoaderConfig{} - m.LoaderConfigName = "test" + m.LoaderConfigName = cfgName err = m.VerifyAndAdjust() c.Assert(terror.ErrConfigLoaderCfgConflict.Equal(err), IsTrue) m.Loader = nil m.Syncer = &SyncerConfig{} - m.SyncerConfigName = "test" + m.SyncerConfigName = cfgName err = m.VerifyAndAdjust() c.Assert(terror.ErrConfigSyncerCfgConflict.Equal(err), IsTrue) m.SyncerConfigName = "" c.Assert(m.VerifyAndAdjust(), IsNil) - } func (t *testConfig) TestAdjustTargetDBConfig(c *C) { diff --git a/dm/ctl/common/config.go b/dm/ctl/common/config.go index 7ee635d657..1e4a38f3ae 100644 --- a/dm/ctl/common/config.go +++ b/dm/ctl/common/config.go @@ -31,14 +31,14 @@ import ( const ( defaultRPCTimeout = "10m" - // EncryptCmdName is special command + // EncryptCmdName is special command. EncryptCmdName = "encrypt" - // DecryptCmdName is special command + // DecryptCmdName is special command. DecryptCmdName = "decrypt" - // Master specifies member master type + // Master specifies member master type. Master = "master" - // Worker specifies member worker type + // Worker specifies member worker type. Worker = "worker" dialTimeout = 3 * time.Second @@ -151,7 +151,7 @@ func (c *Config) Parse(arguments []string) (finish bool, err error) { return false, errors.Trace(c.adjust()) } -// Validate check config is ready to execute command +// Validate check config is ready to execute command. func (c *Config) Validate() error { if c.MasterAddr == "" { return errors.New("--master-addr not provided") @@ -168,7 +168,7 @@ func (c *Config) configFromFile(path string) error { return errors.Trace(err) } -// adjust adjusts configs +// adjust adjusts configs. func (c *Config) adjust() error { if c.RPCTimeoutStr == "" { c.RPCTimeoutStr = defaultRPCTimeout @@ -184,7 +184,7 @@ func (c *Config) adjust() error { return nil } -// validate host:port format address +// validate host:port format address. func validateAddr(addr string) error { endpoints := strings.Split(addr, ",") for _, endpoint := range endpoints { diff --git a/dm/ctl/common/operate_relay.go b/dm/ctl/common/operate_relay.go index 015ad4a78f..26fcd38f92 100644 --- a/dm/ctl/common/operate_relay.go +++ b/dm/ctl/common/operate_relay.go @@ -19,7 +19,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// OperateRelay does operation on relay unit +// OperateRelay does operation on relay unit. func OperateRelay(op pb.RelayOp, workers []string) (*pb.OperateWorkerRelayResponse, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/dm/ctl/common/operate_task.go b/dm/ctl/common/operate_task.go index 4359591891..2dd4c79bd6 100644 --- a/dm/ctl/common/operate_task.go +++ b/dm/ctl/common/operate_task.go @@ -19,7 +19,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// OperateTask does operation on task +// OperateTask does operation on task. func OperateTask(op pb.TaskOp, name string, sources []string) (*pb.OperateTaskResponse, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/dm/ctl/common/util.go b/dm/ctl/common/util.go index 782784eba4..1aea8c6439 100644 --- a/dm/ctl/common/util.go +++ b/dm/ctl/common/util.go @@ -23,12 +23,13 @@ import ( "sync" "time" + "go.etcd.io/etcd/clientv3" + "github.com/pingcap/dm/dm/config" "github.com/pingcap/dm/dm/pb" parserpkg "github.com/pingcap/dm/pkg/parser" "github.com/pingcap/dm/pkg/terror" "github.com/pingcap/dm/pkg/utils" - "go.etcd.io/etcd/clientv3" "github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/proto" @@ -46,7 +47,7 @@ var ( ctlClient = &CtlClient{} ) -// CtlClient used to get master client for dmctl +// CtlClient used to get master client for dmctl. type CtlClient struct { mu sync.RWMutex tls *toolutils.TLS @@ -97,7 +98,7 @@ func (c *CtlClient) sendRequest(ctx context.Context, reqName string, req interfa return errInterface.(error) } -// SendRequest send request to master +// SendRequest send request to master. func SendRequest(ctx context.Context, reqName string, req interface{}, respPointer interface{}) error { err := ctlClient.sendRequest(ctx, reqName, req, respPointer) if err == nil || status.Code(err) != codes.Unavailable { @@ -114,13 +115,13 @@ func SendRequest(ctx context.Context, reqName string, req interface{}, respPoint return ctlClient.sendRequest(ctx, reqName, req, respPointer) } -// InitUtils inits necessary dmctl utils +// InitUtils inits necessary dmctl utils. func InitUtils(cfg *Config) error { globalConfig = cfg return errors.Trace(InitClient(cfg.MasterAddr, cfg.Security)) } -// InitClient initializes dm-master client +// InitClient initializes dm-master client. func InitClient(addr string, securityCfg config.Security) error { tls, err := toolutils.NewTLS(securityCfg.SSLCA, securityCfg.SSLCert, securityCfg.SSLKey, "", securityCfg.CertAllowedCN) if err != nil { @@ -147,31 +148,31 @@ func InitClient(addr string, securityCfg config.Security) error { return ctlClient.updateMasterClient() } -// GlobalConfig returns global dmctl config +// GlobalConfig returns global dmctl config. func GlobalConfig() *Config { return globalConfig } -// PrintLines adds a wrap to support `\n` within `chzyer/readline` -func PrintLines(format string, a ...interface{}) { +// PrintLinesf adds a wrap to support `\n` within `chzyer/readline`. +func PrintLinesf(format string, a ...interface{}) { fmt.Println(fmt.Sprintf(format, a...)) } -// PrettyPrintResponse prints a PRC response prettily +// PrettyPrintResponse prints a PRC response prettily. func PrettyPrintResponse(resp proto.Message) { s, err := marshResponseToString(resp) if err != nil { - PrintLines("%v", err) + PrintLinesf("%v", err) } else { fmt.Println(s) } } -// PrettyPrintInterface prints an interface through encoding/json prettily +// PrettyPrintInterface prints an interface through encoding/json prettily. func PrettyPrintInterface(resp interface{}) { s, err := json.MarshalIndent(resp, "", " ") if err != nil { - PrintLines("%v", err) + PrintLinesf("%v", err) } else { fmt.Println(string(s)) } @@ -236,7 +237,7 @@ func PrettyPrintResponseWithCheckTask(resp proto.Message, subStr string) bool { } if err != nil { - PrintLines("%v", err) + PrintLinesf("%v", err) } else { // add indent to make it prettily. replacedStr = strings.Replace(replacedStr, "detail: {", " \tdetail: {", 1) @@ -245,7 +246,7 @@ func PrettyPrintResponseWithCheckTask(resp proto.Message, subStr string) bool { return found } -// GetFileContent reads and returns file's content +// GetFileContent reads and returns file's content. func GetFileContent(fpath string) ([]byte, error) { content, err := ioutil.ReadFile(fpath) if err != nil { @@ -254,18 +255,18 @@ func GetFileContent(fpath string) ([]byte, error) { return content, nil } -// GetSourceArgs extracts sources from cmd +// GetSourceArgs extracts sources from cmd. func GetSourceArgs(cmd *cobra.Command) ([]string, error) { ret, err := cmd.Flags().GetStringSlice("source") if err != nil { - PrintLines("error in parse `-s` / `--source`") + PrintLinesf("error in parse `-s` / `--source`") } return ret, err } // ExtractSQLsFromArgs extract multiple sql from args. func ExtractSQLsFromArgs(args []string) ([]string, error) { - if len(args) <= 0 { + if len(args) == 0 { return nil, errors.New("args is empty") } @@ -288,7 +289,7 @@ func ExtractSQLsFromArgs(args []string) ([]string, error) { return realSQLs, nil } -// GetTaskNameFromArgOrFile tries to retrieve name from the file if arg is yaml-filename-like, otherwise returns arg directly +// GetTaskNameFromArgOrFile tries to retrieve name from the file if arg is yaml-filename-like, otherwise returns arg directly. func GetTaskNameFromArgOrFile(arg string) string { if !(strings.HasSuffix(arg, ".yaml") || strings.HasSuffix(arg, ".yml")) { return arg @@ -309,13 +310,12 @@ func GetTaskNameFromArgOrFile(arg string) string { // PrintCmdUsage prints the usage of the command. func PrintCmdUsage(cmd *cobra.Command) { - err := cmd.Usage() - if err != nil { + if err := cmd.Usage(); err != nil { fmt.Println("can't output command's usage:", err) } } -// SyncMasterEndpoints sync masters' endpoints +// SyncMasterEndpoints sync masters' endpoints. func SyncMasterEndpoints(ctx context.Context) { lastClientUrls := []string{} clientURLs := []string{} diff --git a/dm/ctl/ctl.go b/dm/ctl/ctl.go index e40b848b54..9ffb0338b8 100644 --- a/dm/ctl/ctl.go +++ b/dm/ctl/ctl.go @@ -31,12 +31,12 @@ var ( rootCmd *cobra.Command ) -// CommandMasterFlags are flags that used in all commands for dm-master +// CommandMasterFlags are flags that used in all commands for dm-master. type CommandMasterFlags struct { workers []string // specify workers to control on these dm-workers } -// Reset clears cache of CommandMasterFlags +// Reset clears cache of CommandMasterFlags. func (c CommandMasterFlags) Reset() { c.workers = c.workers[:0] } @@ -45,7 +45,7 @@ func init() { rootCmd = NewRootCmd() } -// NewRootCmd generates a new rootCmd +// NewRootCmd generates a new rootCmd. func NewRootCmd() *cobra.Command { cmd := &cobra.Command{ Use: "dmctl", @@ -100,7 +100,7 @@ Simply type ` + cmd.Name() + ` help [path to command] for full details.`, return cmd } -// Init initializes dm-control +// Init initializes dm-control. func Init(cfg *common.Config) error { // set the log level temporarily log.SetLevel(zapcore.InfoLevel) @@ -108,7 +108,7 @@ func Init(cfg *common.Config) error { return errors.Trace(common.InitUtils(cfg)) } -// PrintUsage prints usage +// PrintUsage prints usage. func PrintUsage() { maxCmdLen := 0 for _, cmd := range rootCmd.Commands() { @@ -123,7 +123,7 @@ func PrintUsage() { } } -// HasCommand represent whether rootCmd has this command +// HasCommand represent whether rootCmd has this command. func HasCommand(name string) bool { for _, cmd := range rootCmd.Commands() { if name == cmd.Name() { @@ -133,7 +133,7 @@ func HasCommand(name string) bool { return false } -// PrintHelp print help message for special subCommand +// PrintHelp print help message for special subCommand. func PrintHelp(args []string) { cmd, _, err := rootCmd.Find(args) if err != nil { @@ -146,7 +146,7 @@ func PrintHelp(args []string) { common.PrintCmdUsage(cmd) } -// Start starts running a command +// Start starts running a command. func Start(args []string) (err error) { commandMasterFlags.Reset() rootCmd = NewRootCmd() diff --git a/dm/ctl/master/check_task.go b/dm/ctl/master/check_task.go index 736569b0d6..3e772dd259 100644 --- a/dm/ctl/master/check_task.go +++ b/dm/ctl/master/check_task.go @@ -25,7 +25,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewCheckTaskCmd creates a CheckTask command +// NewCheckTaskCmd creates a CheckTask command. func NewCheckTaskCmd() *cobra.Command { cmd := &cobra.Command{ Use: "check-task ", @@ -35,17 +35,16 @@ func NewCheckTaskCmd() *cobra.Command { return cmd } -// checkTaskFunc does check task request -func checkTaskFunc(cmd *cobra.Command, _ []string) (err error) { +// checkTaskFunc does check task request. +func checkTaskFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } content, err := common.GetFileContent(cmd.Flags().Arg(0)) if err != nil { - return + return err } ctx, cancel := context.WithCancel(context.Background()) @@ -63,11 +62,11 @@ func checkTaskFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } if !common.PrettyPrintResponseWithCheckTask(resp, checker.ErrorMsgHeader) { common.PrettyPrintResponse(resp) } - return + return nil } diff --git a/dm/ctl/master/get_config.go b/dm/ctl/master/get_config.go index 3a2e571d56..b6d11862c4 100644 --- a/dm/ctl/master/get_config.go +++ b/dm/ctl/master/get_config.go @@ -26,7 +26,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewGetCfgCmd creates a getCfg command +// NewGetCfgCmd creates a getCfg command. func NewGetCfgCmd() *cobra.Command { cmd := &cobra.Command{ Use: "get-config [--file filename]", @@ -52,28 +52,26 @@ func convertCfgType(t string) pb.CfgType { } } -// getCfgFunc gets config -func getCfgFunc(cmd *cobra.Command, _ []string) (err error) { +// getCfgFunc gets config. +func getCfgFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 2 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } cfgType := cmd.Flags().Arg(0) tp := convertCfgType(cfgType) if tp == pb.CfgType_InvalidType { - common.PrintLines("invalid config type '%s'", cfgType) - err = errors.New("please check output to see error") - return + common.PrintLinesf("invalid config type '%s'", cfgType) + return errors.New("please check output to see error") } cfgName := cmd.Flags().Arg(1) filename, err := cmd.Flags().GetString("file") if err != nil { - common.PrintLines("can not get filename") - return + common.PrintLinesf("can not get filename") + return err } ctx, cancel := context.WithTimeout(context.Background(), common.GlobalConfig().RPCTimeout) @@ -90,19 +88,19 @@ func getCfgFunc(cmd *cobra.Command, _ []string) (err error) { &resp, ) if err != nil { - common.PrintLines("can not get %s config of %s", cfgType, cfgName) - return + common.PrintLinesf("can not get %s config of %s", cfgType, cfgName) + return err } if resp.Result && len(filename) != 0 { - err = ioutil.WriteFile(filename, []byte(resp.Cfg), 0644) + err = ioutil.WriteFile(filename, []byte(resp.Cfg), 0o644) if err != nil { - common.PrintLines("can not write config to file %s", filename) - return + common.PrintLinesf("can not write config to file %s", filename) + return err } resp.Msg = fmt.Sprintf("write config to file %s succeed", filename) resp.Cfg = "" } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/handle_error.go b/dm/ctl/master/handle_error.go index 028952141a..4a26156676 100644 --- a/dm/ctl/master/handle_error.go +++ b/dm/ctl/master/handle_error.go @@ -25,7 +25,7 @@ import ( "github.com/pingcap/dm/pkg/binlog" ) -// NewHandleErrorCmd creates a HandleError command +// NewHandleErrorCmd creates a HandleError command. func NewHandleErrorCmd() *cobra.Command { cmd := &cobra.Command{ Use: "handle-error [-s source ...] [-b binlog-pos] [replace-sql1;replace-sql2;]", @@ -49,58 +49,55 @@ func convertOp(t string) pb.ErrorOp { } } -// handleErrorFunc does handle error request -func handleErrorFunc(cmd *cobra.Command, _ []string) (err error) { +// handleErrorFunc does handle error request. +func handleErrorFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) < 2 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0)) operation := cmd.Flags().Arg(1) var sqls []string + var err error op := convertOp(operation) switch op { case pb.ErrorOp_Skip, pb.ErrorOp_Revert: if len(cmd.Flags().Args()) > 2 { - common.PrintLines("replace-sqls can not be used for 'skip/revert' operation") - err = errors.New("please check output to see error") - return + common.PrintLinesf("replace-sqls can not be used for 'skip/revert' operation") + return errors.New("please check output to see error") } case pb.ErrorOp_Replace: if len(cmd.Flags().Args()) <= 2 { - common.PrintLines("must specify the replace-sqls for replace operation") - err = errors.New("please check output to see error") - return + common.PrintLinesf("must specify the replace-sqls for replace operation") + return errors.New("please check output to see error") } sqls, err = common.ExtractSQLsFromArgs(cmd.Flags().Args()[2:]) if err != nil { - return + return err } default: - common.PrintLines("invalid operation '%s', please use `skip`, `replace` or `revert`", operation) - err = errors.New("please check output to see error") - return + common.PrintLinesf("invalid operation '%s', please use `skip`, `replace` or `revert`", operation) + return errors.New("please check output to see error") } binlogPos, err := cmd.Flags().GetString("binlog-pos") if err != nil { - return + return err } if len(binlogPos) != 0 { _, err = binlog.VerifyBinlogPos(binlogPos) if err != nil { - return + return err } } sources, err := common.GetSourceArgs(cmd) if err != nil { - return + return err } ctx, cancel := context.WithCancel(context.Background()) @@ -121,9 +118,9 @@ func handleErrorFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/list_member.go b/dm/ctl/master/list_member.go index fa14af428c..cdc9a99a20 100644 --- a/dm/ctl/master/list_member.go +++ b/dm/ctl/master/list_member.go @@ -24,16 +24,14 @@ import ( "github.com/pingcap/dm/dm/pb" ) -var ( - listMemberFlags = ListMemberFlags{} -) +var listMemberFlags = ListMemberFlags{} -// ListMemberFlags are flags that used in ListMember command +// ListMemberFlags are flags that used in ListMember command. type ListMemberFlags struct { names []string // specify names to list information } -// NewListMemberCmd creates an ListMember command +// NewListMemberCmd creates an ListMember command. func NewListMemberCmd() *cobra.Command { cmd := &cobra.Command{ Use: "list-member [--leader] [--master] [--worker] [--name master-name/worker-name ...]", @@ -63,18 +61,17 @@ func convertListMemberType(cmd *cobra.Command) (bool, bool, bool, error) { return leader, master, worker, nil } -// listMemberFunc does list member request -func listMemberFunc(cmd *cobra.Command, _ []string) (err error) { +// listMemberFunc does list member request. +func listMemberFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 0 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } leader, master, worker, err := convertListMemberType(cmd) if err != nil { - common.PrintLines("%v", err) + common.PrintLinesf("%v", err) } ctx, cancel := context.WithCancel(context.Background()) @@ -93,8 +90,8 @@ func listMemberFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/offline_member.go b/dm/ctl/master/offline_member.go index 0aade592ac..9b526c317f 100644 --- a/dm/ctl/master/offline_member.go +++ b/dm/ctl/master/offline_member.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/cobra" ) -// NewOfflineMemberCmd creates an OfflineWorker command +// NewOfflineMemberCmd creates an OfflineWorker command. func NewOfflineMemberCmd() *cobra.Command { cmd := &cobra.Command{ Use: "offline-member <--master/--worker> <--name master-name/worker-name>", @@ -55,28 +55,26 @@ func convertOfflineMemberType(cmd *cobra.Command) (string, error) { return common.Worker, nil } -// offlineMemberFunc does offline member request -func offlineMemberFunc(cmd *cobra.Command, _ []string) (err error) { +// offlineMemberFunc does offline member request. +func offlineMemberFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) > 0 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } offlineType, err := convertOfflineMemberType(cmd) if err != nil { - common.PrintLines("get offline type failed") - return + common.PrintLinesf("get offline type failed") + return err } name, err := cmd.Flags().GetString("name") if err != nil { - common.PrintLines("get offline name failed") - return + common.PrintLinesf("get offline name failed") + return err } else if name == "" { - common.PrintLines("a member name must be specified") - err = errors.New("please check output to see error") - return + common.PrintLinesf("a member name must be specified") + return errors.New("please check output to see error") } ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -93,13 +91,12 @@ func offlineMemberFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } if !resp.Result { - common.PrintLines("offline member failed:\n%v", resp.Msg) - err = errors.New("please check output to see error") - return + common.PrintLinesf("offline member failed:\n%v", resp.Msg) + return errors.New("please check output to see error") } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/operate_leader.go b/dm/ctl/master/operate_leader.go index 9086995a59..9a2dce3400 100644 --- a/dm/ctl/master/operate_leader.go +++ b/dm/ctl/master/operate_leader.go @@ -24,7 +24,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewOperateLeaderCmd creates a OperateLeader command +// NewOperateLeaderCmd creates a OperateLeader command. func NewOperateLeaderCmd() *cobra.Command { cmd := &cobra.Command{ Use: "operate-leader ", @@ -45,22 +45,20 @@ func convertOpType(op string) pb.LeaderOp { } } -// operateLeaderFunc does operate leader request -func operateLeaderFunc(cmd *cobra.Command, _ []string) (err error) { +// operateLeaderFunc does operate leader request. +func operateLeaderFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } opType := cmd.Flags().Arg(0) op := convertOpType(opType) if op == pb.LeaderOp_InvalidLeaderOp { - common.PrintLines("invalid operate '%s' on leader", opType) - err = errors.New("please check output to see error") - return + common.PrintLinesf("invalid operate '%s' on leader", opType) + return errors.New("please check output to see error") } ctx, cancel := context.WithCancel(context.Background()) @@ -68,7 +66,7 @@ func operateLeaderFunc(cmd *cobra.Command, _ []string) (err error) { // operate leader resp := &pb.OperateLeaderResponse{} - err = common.SendRequest( + err := common.SendRequest( ctx, "OperateLeader", &pb.OperateLeaderRequest{ @@ -76,11 +74,10 @@ func operateLeaderFunc(cmd *cobra.Command, _ []string) (err error) { }, &resp, ) - if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/operate_schema.go b/dm/ctl/master/operate_schema.go index 0df828cdec..71b15fd1b3 100644 --- a/dm/ctl/master/operate_schema.go +++ b/dm/ctl/master/operate_schema.go @@ -52,78 +52,73 @@ func convertSchemaOpType(t string) pb.SchemaOp { } // operateSchemaCmd does the operate schema request. -func operateSchemaCmd(cmd *cobra.Command, _ []string) (err error) { +func operateSchemaCmd(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) < 2 || len(cmd.Flags().Args()) > 3 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } opType := cmd.Flags().Arg(0) taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(1)) schemaFile := cmd.Flags().Arg(2) + var err error var schemaContent []byte op := convertSchemaOpType(opType) switch op { case pb.SchemaOp_InvalidSchemaOp: - common.PrintLines("invalid operate '%s' on schema", opType) - err = errors.New("please check output to see error") - return + common.PrintLinesf("invalid operate '%s' on schema", opType) + return errors.New("please check output to see error") case pb.SchemaOp_SetSchema: if schemaFile == "" { - common.PrintLines("must sepcify schema file for 'set' operation") - err = errors.New("please check output to see error") - return + common.PrintLinesf("must sepcify schema file for 'set' operation") + return errors.New("please check output to see error") } schemaContent, err = common.GetFileContent(schemaFile) if err != nil { - return + return err } default: if schemaFile != "" { - common.PrintLines("schema file will be ignored for 'get'/'delete' operation") + common.PrintLinesf("schema file will be ignored for 'get'/'delete' operation") } } sources, err := common.GetSourceArgs(cmd) if err != nil { - return + return err } else if len(sources) == 0 { - common.PrintLines("must specify at least one source (`-s` / `--source`)") - err = errors.New("please check output to see error") - return + common.PrintLinesf("must specify at least one source (`-s` / `--source`)") + return errors.New("please check output to see error") } database, err := cmd.Flags().GetString("database") if err != nil { - return + return err } else if database == "" { - common.PrintLines("must specify 'database'") - err = errors.New("please check output to see error") - return + common.PrintLinesf("must specify 'database'") + return errors.New("please check output to see error") } table, err := cmd.Flags().GetString("table") if err != nil { - return + return err } else if table == "" { - common.PrintLines("must specify 'table'") - err = errors.New("please check output to see error") - return + common.PrintLinesf("must specify 'table'") + return errors.New("please check output to see error") } flush, err := cmd.Flags().GetBool("flush") if err != nil { - return + return err } if flush && op != pb.SchemaOp_SetSchema { - err = errors.New("--flush flag is only used to set schema") + return errors.New("--flush flag is only used to set schema") } sync, err := cmd.Flags().GetBool("sync") if err != nil { - return + return err } if sync && op != pb.SchemaOp_SetSchema { - err = errors.New("--sync flag is only used to set schema") + return errors.New("--sync flag is only used to set schema") } ctx, cancel := context.WithCancel(context.Background()) @@ -147,8 +142,8 @@ func operateSchemaCmd(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/operate_source.go b/dm/ctl/master/operate_source.go index 8d55f42e66..8110b2ca33 100644 --- a/dm/ctl/master/operate_source.go +++ b/dm/ctl/master/operate_source.go @@ -28,7 +28,7 @@ import ( "github.com/spf13/cobra" ) -// NewOperateSourceCmd creates a OperateSource command +// NewOperateSourceCmd creates a OperateSource command. func NewOperateSourceCmd() *cobra.Command { cmd := &cobra.Command{ Use: "operate-source [config-file ...] [--print-sample-config]", @@ -54,12 +54,12 @@ func convertCmdType(t string) pb.SourceOp { } } -// operateMysqlFunc does migrate relay request -func operateSourceFunc(cmd *cobra.Command, _ []string) (err error) { +// operateMysqlFunc does migrate relay request. +func operateSourceFunc(cmd *cobra.Command, _ []string) error { printSampleConfig, err := cmd.Flags().GetBool("print-sample-config") if err != nil { - common.PrintLines("error in parse `--print-sample-config`") - return + common.PrintLinesf("error in parse `--print-sample-config`") + return err } if printSampleConfig { @@ -74,26 +74,24 @@ func operateSourceFunc(cmd *cobra.Command, _ []string) (err error) { fmt.Println(string(rawConfig)) } } - return + return nil } if len(cmd.Flags().Args()) < 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } cmdType := cmd.Flags().Arg(0) op := convertCmdType(cmdType) if op == pb.SourceOp_InvalidSourceOp { - common.PrintLines("invalid operate '%s' on worker", cmdType) - err = errors.New("please check output to see error") - return + common.PrintLinesf("invalid operate '%s' on worker", cmdType) + return errors.New("please check output to see error") } if op != pb.SourceOp_ShowSource && len(cmd.Flags().Args()) == 1 { - common.PrintLines("operate-source create/update/stop should specify config-file(s)") - return + common.PrintLinesf("operate-source create/update/stop should specify config-file(s)") + return errors.New("please check output to see error") } contents := make([]string, 0, len(cmd.Flags().Args())-1) @@ -107,7 +105,7 @@ func operateSourceFunc(cmd *cobra.Command, _ []string) (err error) { sourceID = append(sourceID, arg) continue } - return + return err } contents = append(contents, string(content)) } @@ -128,9 +126,9 @@ func operateSourceFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/pause_relay.go b/dm/ctl/master/pause_relay.go index d744394be1..e7277418fe 100644 --- a/dm/ctl/master/pause_relay.go +++ b/dm/ctl/master/pause_relay.go @@ -24,7 +24,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewPauseRelayCmd creates a PauseRelay command +// NewPauseRelayCmd creates a PauseRelay command. func NewPauseRelayCmd() *cobra.Command { cmd := &cobra.Command{ Use: "pause-relay <-s source ...>", @@ -34,7 +34,7 @@ func NewPauseRelayCmd() *cobra.Command { return cmd } -// pauseRelayFunc does pause relay request +// pauseRelayFunc does pause relay request. func pauseRelayFunc(cmd *cobra.Command, _ []string) (err error) { if len(cmd.Flags().Args()) > 0 { cmd.SetOut(os.Stdout) diff --git a/dm/ctl/master/pause_task.go b/dm/ctl/master/pause_task.go index b70a44195a..b08761a589 100644 --- a/dm/ctl/master/pause_task.go +++ b/dm/ctl/master/pause_task.go @@ -23,7 +23,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewPauseTaskCmd creates a PauseTask command +// NewPauseTaskCmd creates a PauseTask command. func NewPauseTaskCmd() *cobra.Command { cmd := &cobra.Command{ Use: "pause-task [-s source ...] ", @@ -33,7 +33,7 @@ func NewPauseTaskCmd() *cobra.Command { return cmd } -// pauseTaskFunc does pause task request +// pauseTaskFunc does pause task request. func pauseTaskFunc(cmd *cobra.Command, _ []string) (err error) { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) @@ -50,7 +50,7 @@ func pauseTaskFunc(cmd *cobra.Command, _ []string) (err error) { resp, err := common.OperateTask(pb.TaskOp_Pause, name, sources) if err != nil { - common.PrintLines("can not pause task %s", name) + common.PrintLinesf("can not pause task %s", name) return } diff --git a/dm/ctl/master/purge_relay.go b/dm/ctl/master/purge_relay.go index bfc5fcfca3..e48aaae53e 100644 --- a/dm/ctl/master/purge_relay.go +++ b/dm/ctl/master/purge_relay.go @@ -31,64 +31,60 @@ import ( // three purge methods supported by dmctl // 1. purge inactive relay log files // 2. purge before time, like `PURGE BINARY LOGS BEFORE` in MySQL -// 3. purge before filename, like `PURGE BINARY LOGS TO` +// 3. purge before filename, like `PURGE BINARY LOGS TO`. func NewPurgeRelayCmd() *cobra.Command { cmd := &cobra.Command{ - //Use: "purge-relay <-w worker> [--inactive] [--time] [--filename] [--sub-dir]", - //Short: "purge dm-worker's relay log files, choose 1 of 2 methods", + // Use: "purge-relay <-w worker> [--inactive] [--time] [--filename] [--sub-dir]", + // Short: "purge dm-worker's relay log files, choose 1 of 2 methods", Use: "purge-relay <-s source> <-f filename> [--sub-dir directory]", Short: "Purges relay log files of the DM-worker according to the specified filename.", RunE: purgeRelayFunc, } - //cmd.Flags().BoolP("inactive", "i", false, "whether try to purge all inactive relay log files") - //cmd.Flags().StringP("time", "t", "", fmt.Sprintf("whether try to purge relay log files before this time, the format is \"%s\"(_ between date and time)", timeFormat)) + // cmd.Flags().BoolP("inactive", "i", false, "whether try to purge all inactive relay log files") + // cmd.Flags().StringP("time", "t", "", fmt.Sprintf("whether try to purge relay log files before this time, the format is \"%s\"(_ between date and time)", timeFormat)) cmd.Flags().StringP("filename", "f", "", "name of the terminal file before which to purge relay log files. Sample format: \"mysql-bin.000006\"") cmd.Flags().StringP("sub-dir", "", "", "specify relay sub directory for --filename. If not specified, the latest one will be used. Sample format: \"2ae76434-f79f-11e8-bde2-0242ac130008.000001\"") return cmd } -// purgeRelayFunc does purge relay log files -func purgeRelayFunc(cmd *cobra.Command, _ []string) (err error) { +// purgeRelayFunc does purge relay log files. +func purgeRelayFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) > 0 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } sources, err := common.GetSourceArgs(cmd) if err != nil { - return + return err } if len(sources) == 0 { - err = errors.New("must specify at least one source (`-s` / `--source`)") - return + return errors.New("must specify at least one source (`-s` / `--source`)") } filename, err := cmd.Flags().GetString("filename") if err != nil { - return + return err } if len(filename) == 0 { - err = errors.New("must specify the name of the terminal file before which to purge relay log files. (`-f` / `--filename`)") - return + return errors.New("must specify the name of the terminal file before which to purge relay log files. (`-f` / `--filename`)") } subDir, err := cmd.Flags().GetString("sub-dir") if err != nil { - return + return err } if len(filename) > 0 { - //count++ + // count++ filename = strings.Trim(filename, "\"") } if len(filename) > 0 && len(sources) > 1 { - err = errors.New("for --filename, can only specify one source per time") - return + return errors.New("for --filename, can only specify one source per time") } if len(subDir) > 0 { subDir = utils.TrimQuoteMark(subDir) @@ -106,8 +102,8 @@ func purgeRelayFunc(cmd *cobra.Command, _ []string) (err error) { "PurgeWorkerRelay", &pb.PurgeWorkerRelayRequest{ Sources: sources, - //Inactive: inactive, - //Time: time2.Unix(), + // Inactive: inactive, + // Time: time2.Unix(), Filename: filename, SubDir: subDir, }, @@ -115,9 +111,9 @@ func purgeRelayFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/query_status.go b/dm/ctl/master/query_status.go index 2ae5305ebc..13686d2217 100644 --- a/dm/ctl/master/query_status.go +++ b/dm/ctl/master/query_status.go @@ -39,7 +39,7 @@ type taskInfo struct { Sources []string `json:"sources,omitempty"` } -// NewQueryStatusCmd creates a QueryStatus command +// NewQueryStatusCmd creates a QueryStatus command. func NewQueryStatusCmd() *cobra.Command { cmd := &cobra.Command{ Use: "query-status [-s source ...] [task-name | task-file] [--more]", @@ -50,19 +50,18 @@ func NewQueryStatusCmd() *cobra.Command { return cmd } -// queryStatusFunc does query task's status -func queryStatusFunc(cmd *cobra.Command, _ []string) (err error) { +// queryStatusFunc does query task's status. +func queryStatusFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) > 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0)) // maybe empty sources, err := common.GetSourceArgs(cmd) if err != nil { - return + return err } ctx, cancel := context.WithTimeout(context.Background(), common.GlobalConfig().RPCTimeout) @@ -80,33 +79,33 @@ func queryStatusFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - common.PrintLines("can not query %s task's status(in sources %v)", taskName, sources) - return + common.PrintLinesf("can not query %s task's status(in sources %v)", taskName, sources) + return err } more, err := cmd.Flags().GetBool("more") if err != nil { - common.PrintLines("error in parse `--more`") - return + common.PrintLinesf("error in parse `--more`") + return err } if resp.Result && taskName == "" && len(sources) == 0 && !more { result, hasFalseResult := wrapTaskResult(resp) if !hasFalseResult { // if any result is false, we still print the full status. common.PrettyPrintInterface(result) - return + return nil } } common.PrettyPrintResponse(resp) - return + return nil } -// errorOccurred checks ProcessResult and return true if some error occurred +// errorOccurred checks ProcessResult and return true if some error occurred. func errorOccurred(result *pb.ProcessResult) bool { return result != nil && len(result.Errors) > 0 } -// getRelayStage returns current relay stage (including stageError) +// getRelayStage returns current relay stage (including stageError). func getRelayStage(relayStatus *pb.RelayStatus) string { if errorOccurred(relayStatus.Result) { return stageError @@ -114,7 +113,7 @@ func getRelayStage(relayStatus *pb.RelayStatus) string { return relayStatus.Stage.String() } -// wrapTaskResult picks task info and generate tasks' status and relative workers +// wrapTaskResult picks task info and generate tasks' status and relative workers. func wrapTaskResult(resp *pb.QueryStatusListResponse) (result *taskResult, hasFalseResult bool) { taskStatusMap := make(map[string]string) taskCorrespondingSources := make(map[string][]string) diff --git a/dm/ctl/master/query_status_test.go b/dm/ctl/master/query_status_test.go index 0935f3c171..e1b8d84967 100644 --- a/dm/ctl/master/query_status_test.go +++ b/dm/ctl/master/query_status_test.go @@ -26,8 +26,7 @@ func TestCtlMaster(t *testing.T) { check.TestingT(t) } -type testCtlMaster struct { -} +type testCtlMaster struct{} var _ = check.Suite(&testCtlMaster{}) @@ -97,7 +96,8 @@ func (t *testCtlMaster) TestWrapTaskResult(c *check.C) { Stage: pb.Stage_Paused, Result: &pb.ProcessResult{ Errors: []*pb.ProcessError{{}}, - }} + }, + } expectedResult[0].TaskStatus = stageError + " - Relay status is " + stageError + extraInfo generateAndCheckTaskResult(c, resp, expectedResult) // relay status is Paused @@ -144,15 +144,16 @@ func (t *testCtlMaster) TestWrapTaskResult(c *check.C) { result.Tasks[0], result.Tasks[1] = result.Tasks[1], result.Tasks[0] } sort.Strings(result.Tasks[0].Sources) - expectedResult = []*taskInfo{{ - TaskName: "test", - TaskStatus: pb.Stage_Running.String(), - Sources: []string{"mysql-replica-01", "mysql-replica-02", "mysql-replica-03"}, - }, { - TaskName: "test2", - TaskStatus: stageError + " - Some error occurred in subtask. Please run `query-status test2` to get more details.", - Sources: []string{"mysql-replica-04"}, - }, + expectedResult = []*taskInfo{ + { + TaskName: "test", + TaskStatus: pb.Stage_Running.String(), + Sources: []string{"mysql-replica-01", "mysql-replica-02", "mysql-replica-03"}, + }, { + TaskName: "test2", + TaskStatus: stageError + " - Some error occurred in subtask. Please run `query-status test2` to get more details.", + Sources: []string{"mysql-replica-04"}, + }, } c.Assert(result.Tasks, check.DeepEquals, expectedResult) diff --git a/dm/ctl/master/resume_relay.go b/dm/ctl/master/resume_relay.go index 2de86e358d..4db456bd11 100644 --- a/dm/ctl/master/resume_relay.go +++ b/dm/ctl/master/resume_relay.go @@ -24,7 +24,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewResumeRelayCmd creates a ResumeRelay command +// NewResumeRelayCmd creates a ResumeRelay command. func NewResumeRelayCmd() *cobra.Command { cmd := &cobra.Command{ Use: "resume-relay <-s source ...>", @@ -34,7 +34,7 @@ func NewResumeRelayCmd() *cobra.Command { return cmd } -// resumeRelayFunc does resume relay request +// resumeRelayFunc does resume relay request. func resumeRelayFunc(cmd *cobra.Command, _ []string) (err error) { if len(cmd.Flags().Args()) > 0 { cmd.SetOut(os.Stdout) diff --git a/dm/ctl/master/resume_task.go b/dm/ctl/master/resume_task.go index 1b78d651ee..9cb2f5edad 100644 --- a/dm/ctl/master/resume_task.go +++ b/dm/ctl/master/resume_task.go @@ -23,7 +23,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewResumeTaskCmd creates a ResumeTask command +// NewResumeTaskCmd creates a ResumeTask command. func NewResumeTaskCmd() *cobra.Command { cmd := &cobra.Command{ Use: "resume-task [-s source ...] ", @@ -33,7 +33,7 @@ func NewResumeTaskCmd() *cobra.Command { return cmd } -// resumeTaskFunc does resume task request +// resumeTaskFunc does resume task request. func resumeTaskFunc(cmd *cobra.Command, _ []string) (err error) { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) @@ -50,7 +50,7 @@ func resumeTaskFunc(cmd *cobra.Command, _ []string) (err error) { resp, err := common.OperateTask(pb.TaskOp_Resume, name, sources) if err != nil { - common.PrintLines("can not resume task %s", name) + common.PrintLinesf("can not resume task %s", name) return } diff --git a/dm/ctl/master/show_ddl_locks.go b/dm/ctl/master/show_ddl_locks.go index c7007ddfc2..9a9ac3df53 100644 --- a/dm/ctl/master/show_ddl_locks.go +++ b/dm/ctl/master/show_ddl_locks.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/cobra" ) -// NewShowDDLLocksCmd creates a ShowDDlLocks command +// NewShowDDLLocksCmd creates a ShowDDlLocks command. func NewShowDDLLocksCmd() *cobra.Command { cmd := &cobra.Command{ Use: "show-ddl-locks [-s source ...] [task-name | task-file]", @@ -34,19 +34,18 @@ func NewShowDDLLocksCmd() *cobra.Command { return cmd } -// showDDLLocksFunc does show DDL locks -func showDDLLocksFunc(cmd *cobra.Command, _ []string) (err error) { +// showDDLLocksFunc does show DDL locks. +func showDDLLocksFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) > 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0)) // maybe empty sources, err := common.GetSourceArgs(cmd) if err != nil { - return + return err } ctx, cancel := context.WithCancel(context.Background()) @@ -64,10 +63,10 @@ func showDDLLocksFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - common.PrintLines("can not show DDL locks for task %s and sources %v", taskName, sources) - return + common.PrintLinesf("can not show DDL locks for task %s and sources %v", taskName, sources) + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/start_relay.go b/dm/ctl/master/start_stop_relay.go similarity index 62% rename from dm/ctl/master/start_relay.go rename to dm/ctl/master/start_stop_relay.go index da4bfdc1aa..f7c411007d 100644 --- a/dm/ctl/master/start_relay.go +++ b/dm/ctl/master/start_stop_relay.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/cobra" ) -// NewStartRelayCmd creates a StartRelay command +// NewStartRelayCmd creates a StartRelay command. func NewStartRelayCmd() *cobra.Command { cmd := &cobra.Command{ Use: "start-relay <-s source-id> [...worker-name]", @@ -34,7 +34,25 @@ func NewStartRelayCmd() *cobra.Command { return cmd } -func startRelayFunc(cmd *cobra.Command, _ []string) (err error) { +// NewStopRelayCmd creates a StartRelay command. +func NewStopRelayCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "stop-relay <-s source-id> [...worker-name]", + Short: "Stops workers pulling relay log for a source.", + RunE: stopRelayFunc, + } + return cmd +} + +func startRelayFunc(cmd *cobra.Command, _ []string) error { + return startStopRelay(cmd, pb.RelayOpV2_StartRelayV2) +} + +func stopRelayFunc(cmd *cobra.Command, _ []string) error { + return startStopRelay(cmd, pb.RelayOpV2_StopRelayV2) +} + +func startStopRelay(cmd *cobra.Command, op pb.RelayOpV2) error { sources, err := common.GetSourceArgs(cmd) if err != nil { return err @@ -46,16 +64,14 @@ func startRelayFunc(cmd *cobra.Command, _ []string) (err error) { // all args empty common.PrintCmdUsage(cmd) } else { - common.PrintLines("must specify at least one worker") + common.PrintLinesf("must specify at least one worker") } - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } if len(sources) != 1 { - common.PrintLines("must specify one source (`-s` / `--source`)") - err = errors.New("please check output to see error") - return + common.PrintLinesf("must specify one source (`-s` / `--source`)") + return errors.New("please check output to see error") } workers := cmd.Flags().Args() @@ -68,7 +84,7 @@ func startRelayFunc(cmd *cobra.Command, _ []string) (err error) { ctx, "OperateRelay", &pb.OperateRelayRequest{ - Op: pb.RelayOpV2_StartRelayV2, + Op: op, Source: sources[0], Worker: workers, }, @@ -76,9 +92,9 @@ func startRelayFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/start_task.go b/dm/ctl/master/start_task.go index 5a8287fe73..8b1f130489 100644 --- a/dm/ctl/master/start_task.go +++ b/dm/ctl/master/start_task.go @@ -25,7 +25,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewStartTaskCmd creates a StartTask command +// NewStartTaskCmd creates a StartTask command. func NewStartTaskCmd() *cobra.Command { cmd := &cobra.Command{ Use: "start-task [-s source ...] [--remove-meta] ", @@ -36,28 +36,27 @@ func NewStartTaskCmd() *cobra.Command { return cmd } -// startTaskFunc does start task request -func startTaskFunc(cmd *cobra.Command, _ []string) (err error) { +// startTaskFunc does start task request. +func startTaskFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } content, err := common.GetFileContent(cmd.Flags().Arg(0)) if err != nil { - return + return err } sources, err := common.GetSourceArgs(cmd) if err != nil { - return + return err } removeMeta, err := cmd.Flags().GetBool("remove-meta") if err != nil { - common.PrintLines("error in parse `--remove-meta`") - return + common.PrintLinesf("error in parse `--remove-meta`") + return err } ctx, cancel := context.WithCancel(context.Background()) @@ -77,11 +76,11 @@ func startTaskFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } if !common.PrettyPrintResponseWithCheckTask(resp, checker.ErrorMsgHeader) { common.PrettyPrintResponse(resp) } - return + return nil } diff --git a/dm/ctl/master/stop_relay.go b/dm/ctl/master/stop_relay.go deleted file mode 100644 index 660a8467bc..0000000000 --- a/dm/ctl/master/stop_relay.go +++ /dev/null @@ -1,84 +0,0 @@ -// 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. - -package master - -import ( - "context" - "errors" - "os" - - "github.com/pingcap/dm/dm/ctl/common" - "github.com/pingcap/dm/dm/pb" - - "github.com/spf13/cobra" -) - -// NewStopRelayCmd creates a StartRelay command -func NewStopRelayCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "stop-relay <-s source-id> [...worker-name]", - Short: "Stops workers pulling relay log for a source.", - RunE: stopRelayFunc, - } - return cmd -} - -func stopRelayFunc(cmd *cobra.Command, _ []string) (err error) { - sources, err := common.GetSourceArgs(cmd) - if err != nil { - return err - } - - if len(cmd.Flags().Args()) == 0 { - cmd.SetOut(os.Stdout) - if len(sources) == 0 { - // all args empty - common.PrintCmdUsage(cmd) - } else { - common.PrintLines("must specify at least one worker") - } - err = errors.New("please check output to see error") - return - } - - if len(sources) != 1 { - common.PrintLines("must specify one source (`-s` / `--source`)") - err = errors.New("please check output to see error") - return - } - - workers := cmd.Flags().Args() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - resp := &pb.OperateRelayResponse{} - err = common.SendRequest( - ctx, - "OperateRelay", - &pb.OperateRelayRequest{ - Op: pb.RelayOpV2_StopRelayV2, - Source: sources[0], - Worker: workers, - }, - &resp, - ) - - if err != nil { - return - } - - common.PrettyPrintResponse(resp) - return -} diff --git a/dm/ctl/master/stop_task.go b/dm/ctl/master/stop_task.go index 1b584f4d22..cb4d6b20a9 100644 --- a/dm/ctl/master/stop_task.go +++ b/dm/ctl/master/stop_task.go @@ -23,7 +23,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewStopTaskCmd creates a StopTask command +// NewStopTaskCmd creates a StopTask command. func NewStopTaskCmd() *cobra.Command { cmd := &cobra.Command{ Use: "stop-task [-s source ...] ", @@ -33,7 +33,7 @@ func NewStopTaskCmd() *cobra.Command { return cmd } -// stopTaskFunc does stop task request +// stopTaskFunc does stop task request. func stopTaskFunc(cmd *cobra.Command, _ []string) (err error) { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) diff --git a/dm/ctl/master/transfer_source.go b/dm/ctl/master/transfer_source.go index 3b6574008d..b35c4a5417 100644 --- a/dm/ctl/master/transfer_source.go +++ b/dm/ctl/master/transfer_source.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/cobra" ) -// NewTransferSourceCmd creates a TransferSource command +// NewTransferSourceCmd creates a TransferSource command. func NewTransferSourceCmd() *cobra.Command { cmd := &cobra.Command{ Use: "transfer-source ", @@ -34,16 +34,16 @@ func NewTransferSourceCmd() *cobra.Command { return cmd } -func transferSourceFunc(cmd *cobra.Command, _ []string) (err error) { +func transferSourceFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 2 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } sourceID := cmd.Flags().Arg(0) workerID := cmd.Flags().Arg(1) + var err error ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -60,9 +60,9 @@ func transferSourceFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/unlock_ddl_lock.go b/dm/ctl/master/unlock_ddl_lock.go index 7b38fc69ee..9630967aae 100644 --- a/dm/ctl/master/unlock_ddl_lock.go +++ b/dm/ctl/master/unlock_ddl_lock.go @@ -25,7 +25,7 @@ import ( "github.com/spf13/cobra" ) -// NewUnlockDDLLockCmd creates a UnlockDDLLock command +// NewUnlockDDLLockCmd creates a UnlockDDLLock command. func NewUnlockDDLLockCmd() *cobra.Command { cmd := &cobra.Command{ Use: "unlock-ddl-lock ", @@ -37,18 +37,17 @@ func NewUnlockDDLLockCmd() *cobra.Command { return cmd } -// unlockDDLLockFunc does unlock DDL lock -func unlockDDLLockFunc(cmd *cobra.Command, _ []string) (err error) { +// unlockDDLLockFunc does unlock DDL lock. +func unlockDDLLockFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } owner, err := cmd.Flags().GetString("owner") if err != nil { - common.PrintLines("error in parse `--owner`") - return + common.PrintLinesf("error in parse `--owner`") + return err } lockID := cmd.Flags().Arg(0) @@ -56,13 +55,12 @@ func unlockDDLLockFunc(cmd *cobra.Command, _ []string) (err error) { sources, _ := common.GetSourceArgs(cmd) if len(sources) > 0 { fmt.Println("shoud not specify any sources") - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } forceRemove, err := cmd.Flags().GetBool("force-remove") if err != nil { - return + return err } ctx, cancel := context.WithCancel(context.Background()) @@ -81,10 +79,10 @@ func unlockDDLLockFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - common.PrintLines("can not unlock DDL lock %s", lockID) - return + common.PrintLinesf("can not unlock DDL lock %s", lockID) + return err } common.PrettyPrintResponse(resp) - return + return nil } diff --git a/dm/ctl/master/update_task.go b/dm/ctl/master/update_task.go index cdecd1f4bb..9da52e0e17 100644 --- a/dm/ctl/master/update_task.go +++ b/dm/ctl/master/update_task.go @@ -25,7 +25,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// NewUpdateTaskCmd creates a UpdateTask command +// NewUpdateTaskCmd creates a UpdateTask command. func NewUpdateTaskCmd() *cobra.Command { cmd := &cobra.Command{ Use: "update-task [-s source ...] ", @@ -35,22 +35,21 @@ func NewUpdateTaskCmd() *cobra.Command { return cmd } -// updateTaskFunc does update task request -func updateTaskFunc(cmd *cobra.Command, _ []string) (err error) { +// updateTaskFunc does update task request. +func updateTaskFunc(cmd *cobra.Command, _ []string) error { if len(cmd.Flags().Args()) != 1 { cmd.SetOut(os.Stdout) common.PrintCmdUsage(cmd) - err = errors.New("please check output to see error") - return + return errors.New("please check output to see error") } content, err := common.GetFileContent(cmd.Flags().Arg(0)) if err != nil { - return + return err } sources, err := common.GetSourceArgs(cmd) if err != nil { - return + return err } ctx, cancel := context.WithCancel(context.Background()) @@ -69,11 +68,11 @@ func updateTaskFunc(cmd *cobra.Command, _ []string) (err error) { ) if err != nil { - return + return err } if !common.PrettyPrintResponseWithCheckTask(resp, checker.ErrorMsgHeader) { common.PrettyPrintResponse(resp) } - return + return nil } diff --git a/dm/master/agent_pool.go b/dm/master/agent_pool.go index 8227181421..ffb8c60034 100644 --- a/dm/master/agent_pool.go +++ b/dm/master/agent_pool.go @@ -23,7 +23,7 @@ import ( "golang.org/x/time/rate" ) -// rate limit related constant value +// rate limit related constant value. const ( DefaultRate = float64(10) DefaultBurst = 40 @@ -35,7 +35,7 @@ type emitFunc func(args ...interface{}) // AgentPool is a pool to control communication with dm-workers // It provides rate limit control for agent acquire, including dispatch rate r // and permits bursts of at most b tokens. -// caller shouldn't to hold agent to avoid deadlock +// caller shouldn't to hold agent to avoid deadlock. type AgentPool struct { requests chan int agents chan *Agent @@ -43,18 +43,18 @@ type AgentPool struct { limiter *rate.Limiter } -// RateLimitConfig holds rate limit config +// RateLimitConfig holds rate limit config. type RateLimitConfig struct { rate float64 // dispatch rate burst int // max permits bursts } -// Agent communicate with dm-workers +// Agent communicate with dm-workers. type Agent struct { ID int } -// NewAgentPool returns a agent pool +// NewAgentPool returns a agent pool. func NewAgentPool(cfg *RateLimitConfig) *AgentPool { requests := make(chan int, int(math.Ceil(1/cfg.rate))+cfg.burst) agents := make(chan *Agent, cfg.burst) @@ -69,7 +69,7 @@ func NewAgentPool(cfg *RateLimitConfig) *AgentPool { } // Apply applies for a agent -// if ctx is canceled before we get an agent, returns nil +// if ctx is canceled before we get an agent, returns nil. func (ap *AgentPool) Apply(ctx context.Context, id int) *Agent { select { case <-ctx.Done(): @@ -85,7 +85,7 @@ func (ap *AgentPool) Apply(ctx context.Context, id int) *Agent { } } -// Start starts AgentPool background dispatcher +// Start starts AgentPool background dispatcher. func (ap *AgentPool) Start(ctx context.Context) { for { select { @@ -108,10 +108,9 @@ func (ap *AgentPool) Start(ctx context.Context) { } } -// Emit applies for an agent to communicates with dm-worker +// Emit applies for an agent to communicates with dm-worker. func (ap *AgentPool) Emit(ctx context.Context, id int, fn emitFunc, errFn emitFunc, args ...interface{}) { - agent := ap.Apply(ctx, id) - if agent == nil { + if agent := ap.Apply(ctx, id); agent == nil { errFn(args...) } else { fn(args...) diff --git a/dm/master/bootstrap_test.go b/dm/master/bootstrap_test.go index b4ce9ccd65..66bf4b0b03 100644 --- a/dm/master/bootstrap_test.go +++ b/dm/master/bootstrap_test.go @@ -86,10 +86,10 @@ func (t *testMaster) TestCollectSourceConfigFilesV1Import(c *C) { // write into source files. data1, err := cfg1.Yaml() c.Assert(err, IsNil) - c.Assert(ioutil.WriteFile(filepath.Join(s.cfg.V1SourcesPath, "source1.yaml"), []byte(data1), 0644), IsNil) + c.Assert(ioutil.WriteFile(filepath.Join(s.cfg.V1SourcesPath, "source1.yaml"), []byte(data1), 0o644), IsNil) data2, err := cfg2.Yaml() c.Assert(err, IsNil) - c.Assert(ioutil.WriteFile(filepath.Join(s.cfg.V1SourcesPath, "source2.yaml"), []byte(data2), 0644), IsNil) + c.Assert(ioutil.WriteFile(filepath.Join(s.cfg.V1SourcesPath, "source2.yaml"), []byte(data2), 0o644), IsNil) // collect again, two configs exist. cfgs, err = s.collectSourceConfigFilesV1Import(tctx) @@ -99,7 +99,7 @@ func (t *testMaster) TestCollectSourceConfigFilesV1Import(c *C) { c.Assert(cfgs[cfg2.SourceID], DeepEquals, *cfg2) // put a invalid source file. - c.Assert(ioutil.WriteFile(filepath.Join(s.cfg.V1SourcesPath, "invalid.yaml"), []byte("invalid-source-data"), 0644), IsNil) + c.Assert(ioutil.WriteFile(filepath.Join(s.cfg.V1SourcesPath, "invalid.yaml"), []byte("invalid-source-data"), 0o644), IsNil) cfgs, err = s.collectSourceConfigFilesV1Import(tctx) c.Assert(terror.ErrConfigYamlTransform.Equal(err), IsTrue) c.Assert(cfgs, HasLen, 0) diff --git a/dm/master/config.go b/dm/master/config.go index 10f7f71c88..eb1f36ff78 100644 --- a/dm/master/config.go +++ b/dm/master/config.go @@ -53,11 +53,11 @@ var ( EnableZap = false // SampleConfigFile is sample config file of dm-master // later we can read it from dm/master/dm-master.toml - // and assign it to SampleConfigFile while we build dm-master + // and assign it to SampleConfigFile while we build dm-master. SampleConfigFile string ) -// NewConfig creates a config for dm-master +// NewConfig creates a config for dm-master. func NewConfig() *Config { cfg := &Config{} cfg.flagSet = flag.NewFlagSet("dm-master", flag.ContinueOnError) @@ -71,7 +71,7 @@ func NewConfig() *Config { fs.StringVar(&cfg.LogLevel, "L", "info", "log level: debug, info, warn, error, fatal") fs.StringVar(&cfg.LogFile, "log-file", "", "log file path") fs.StringVar(&cfg.LogFormat, "log-format", "text", `the format of the log, "text" or "json"`) - //fs.StringVar(&cfg.LogRotate, "log-rotate", "day", "log file rotate type, hour/day") + // fs.StringVar(&cfg.LogRotate, "log-rotate", "day", "log file rotate type, hour/day") fs.StringVar(&cfg.Name, "name", "", "human-readable name for this DM-master member") fs.StringVar(&cfg.DataDir, "data-dir", "", `path to the data directory (default "default.${name}")`) @@ -93,7 +93,7 @@ func NewConfig() *Config { return cfg } -// Config is the configuration for dm-master +// Config is the configuration for dm-master. type Config struct { flagSet *flag.FlagSet @@ -138,7 +138,6 @@ type Config struct { } func (c *Config) String() string { - //nolint:staticcheck cfg, err := json.Marshal(c) if err != nil { log.L().Error("marshal to json", zap.Reflect("master config", c), log.ShortError(err)) @@ -146,7 +145,7 @@ func (c *Config) String() string { return string(cfg) } -// Toml returns TOML format representation of config +// Toml returns TOML format representation of config. func (c *Config) Toml() (string, error) { var b bytes.Buffer @@ -223,7 +222,7 @@ func (c *Config) configFromFile(path string) error { return nil } -// adjust adjusts configs +// adjust adjusts configs. func (c *Config) adjust() error { c.MasterAddr = utils.UnwrapScheme(c.MasterAddr) // MasterAddr's format may be "host:port" or ":port" @@ -321,7 +320,7 @@ func (c *Config) adjust() error { return err } -// Reload load config from local file +// Reload load config from local file. func (c *Config) Reload() error { if c.ConfigFile != "" { err := c.configFromFile(c.ConfigFile) @@ -428,7 +427,7 @@ func genEmbedEtcdConfigWithLogger(logLevel string) *embed.Config { cfg := embed.NewConfig() // disable grpc gateway because https://github.com/etcd-io/etcd/issues/12713 // TODO: wait above issue fixed - //cfg.EnableGRPCGateway = true // enable gRPC gateway for the internal etcd. + // cfg.EnableGRPCGateway = true // enable gRPC gateway for the internal etcd. // use zap as the logger for embed etcd // NOTE: `genEmbedEtcdConfig` can only be called after logger initialized. diff --git a/dm/master/config_test.go b/dm/master/config_test.go index 7c9748de9a..3a39ec5256 100644 --- a/dm/master/config_test.go +++ b/dm/master/config_test.go @@ -36,8 +36,7 @@ var ( _ = check.Suite(&testConfigSuite{}) ) -type testConfigSuite struct { -} +type testConfigSuite struct{} func (t *testConfigSuite) SetUpSuite(c *check.C) { // initialized the logger to make genEmbedEtcdConfig working. @@ -156,7 +155,7 @@ func (t *testConfigSuite) TestInvalidConfig(c *check.C) { master-addr = ":8261" advertise-addr = "127.0.0.1:8261" aaa = "xxx"`) - err = ioutil.WriteFile(filepath, configContent, 0644) + err = ioutil.WriteFile(filepath, configContent, 0o644) c.Assert(err, check.IsNil) err = cfg.configFromFile(filepath) c.Assert(err, check.NotNil) @@ -165,7 +164,7 @@ aaa = "xxx"`) // invalid `master-addr` filepath2 := path.Join(c.MkDir(), "test_invalid_config.toml") configContent2 := []byte(`master-addr = ""`) - err = ioutil.WriteFile(filepath2, configContent2, 0644) + err = ioutil.WriteFile(filepath2, configContent2, 0o644) c.Assert(err, check.IsNil) err = cfg.configFromFile(filepath2) c.Assert(err, check.IsNil) diff --git a/dm/master/election_test.go b/dm/master/election_test.go index 5304cb2a0b..df1cd3ed80 100644 --- a/dm/master/election_test.go +++ b/dm/master/election_test.go @@ -29,8 +29,7 @@ import ( var _ = check.Suite(&testElectionSuite{}) -type testElectionSuite struct { -} +type testElectionSuite struct{} func (t *testMaster) TestFailToStartLeader(c *check.C) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) diff --git a/dm/master/etcd.go b/dm/master/etcd.go index 795daba2ce..3ac9e236e6 100644 --- a/dm/master/etcd.go +++ b/dm/master/etcd.go @@ -33,10 +33,10 @@ import ( ) const ( - // time waiting for etcd to be started + // time waiting for etcd to be started. etcdStartTimeout = time.Minute // privateDirMode grants owner to make/remove files inside the directory. - privateDirMode os.FileMode = 0700 + privateDirMode os.FileMode = 0o700 ) // startEtcd starts an embedded etcd server. @@ -197,7 +197,7 @@ func prepareJoinEtcd(cfg *Config) error { return nil } -// isDataExist returns whether the directory is empty (with data) +// isDataExist returns whether the directory is empty (with data). func isDataExist(d string) bool { dir, err := os.Open(d) if err != nil { diff --git a/dm/master/etcd_test.go b/dm/master/etcd_test.go index 92aad9ebe2..b6086b5cab 100644 --- a/dm/master/etcd_test.go +++ b/dm/master/etcd_test.go @@ -32,8 +32,7 @@ import ( var _ = check.Suite(&testEtcdSuite{}) -type testEtcdSuite struct { -} +type testEtcdSuite struct{} func (t *testEtcdSuite) SetUpSuite(c *check.C) { // initialized the logger to make genEmbedEtcdConfig working. diff --git a/dm/master/http_handler.go b/dm/master/http_handler.go index 4c700d35f0..a20d9b23f2 100644 --- a/dm/master/http_handler.go +++ b/dm/master/http_handler.go @@ -29,8 +29,7 @@ import ( ) // statusHandler handles process status. -type statusHandler struct { -} +type statusHandler struct{} func (h *statusHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") diff --git a/dm/master/metrics/metrics.go b/dm/master/metrics/metrics.go index 478e51c755..e5043c0dab 100644 --- a/dm/master/metrics/metrics.go +++ b/dm/master/metrics/metrics.go @@ -24,14 +24,14 @@ import ( ) // used for ddlPendingCounter, no "Resolved" lock because they will be -// remove quickly and not pending anymore +// remove quickly and not pending anymore. const ( DDLPendingNone = "None" DDLPendingUnSynced = "Un-synced" DDLPendingSynced = "Synced" ) -// used to show error type when handle DDLs +// used to show error type when handle DDLs. const ( InfoErrSyncLock = "InfoPut - SyncLockError" InfoErrHandleLock = "InfoPut - HandleLockError" @@ -40,7 +40,7 @@ const ( OpErrPutNonOwnerOp = "OperationPut - PutNonOwnerOpError" ) -// used to represent worker event error type +// used to represent worker event error type. const ( WorkerEventHandle = "handle" WorkerEventWatch = "watch" @@ -101,7 +101,7 @@ func collectMetrics() { cpuUsageGauge.Set(cpuUsage) } -// RunBackgroundJob do periodic job +// RunBackgroundJob do periodic job. func RunBackgroundJob(ctx context.Context) { ticker := time.NewTicker(time.Second * 10) defer ticker.Stop() @@ -117,7 +117,7 @@ func RunBackgroundJob(ctx context.Context) { } } -// RegistryMetrics registries metrics for worker +// RegistryMetrics registries metrics for worker. func RegistryMetrics() { registry := prometheus.DefaultRegisterer @@ -129,42 +129,42 @@ func RegistryMetrics() { registry.MustRegister(startLeaderCounter) } -// ReportWorkerStage is a setter for workerState +// ReportWorkerStage is a setter for workerState. func ReportWorkerStage(name string, state float64) { workerState.WithLabelValues(name).Set(state) } -// RemoveWorkerState cleans state of deleted worker +// RemoveWorkerState cleans state of deleted worker. func RemoveWorkerState(name string) { workerState.DeleteAllAboutLabels(prometheus.Labels{"worker": name}) } -// ReportDDLPending inc/dec by 1 to ddlPendingCounter -func ReportDDLPending(task, old, new string) { - if old != DDLPendingNone { - ddlPendingCounter.WithLabelValues(task, old).Dec() +// ReportDDLPending inc/dec by 1 to ddlPendingCounter. +func ReportDDLPending(task, oldStatus, newStatus string) { + if oldStatus != DDLPendingNone { + ddlPendingCounter.WithLabelValues(task, oldStatus).Dec() } - if new != DDLPendingNone { - ddlPendingCounter.WithLabelValues(task, new).Inc() + if newStatus != DDLPendingNone { + ddlPendingCounter.WithLabelValues(task, newStatus).Inc() } } -// ReportDDLError is a setter for ddlErrCounter +// ReportDDLError is a setter for ddlErrCounter. func ReportDDLError(task, errType string) { ddlErrCounter.WithLabelValues(task, errType).Inc() } -// ReportWorkerEventErr is a setter for workerEventErrCounter +// ReportWorkerEventErr is a setter for workerEventErrCounter. func ReportWorkerEventErr(errType string) { workerEventErrCounter.WithLabelValues(errType).Inc() } -// ReportStartLeader increases startLeaderCounter by one +// ReportStartLeader increases startLeaderCounter by one. func ReportStartLeader() { startLeaderCounter.Inc() } -// OnRetireLeader cleans some metrics when retires +// OnRetireLeader cleans some metrics when retires. func OnRetireLeader() { workerState.Reset() ddlErrCounter.Reset() diff --git a/dm/master/scheduler/scheduler.go b/dm/master/scheduler/scheduler.go index a7c84f5be4..ff0389b35e 100644 --- a/dm/master/scheduler/scheduler.go +++ b/dm/master/scheduler/scheduler.go @@ -346,7 +346,7 @@ func (s *Scheduler) RemoveSourceCfg(source string) error { return nil } -// GetSourceCfgIDs gets all added source ID +// GetSourceCfgIDs gets all added source ID. func (s *Scheduler) GetSourceCfgIDs() []string { s.mu.RLock() defer s.mu.RUnlock() @@ -370,7 +370,7 @@ func (s *Scheduler) GetSourceCfgByID(source string) *config.SourceConfig { return &clone } -// TransferSource unbinds the source and binds it to a free worker. If fails halfway, the old worker should try recover +// TransferSource unbinds the source and binds it to a free worker. If fails halfway, the old worker should try recover. func (s *Scheduler) TransferSource(source, worker string) error { s.mu.Lock() defer s.mu.Unlock() @@ -393,8 +393,7 @@ func (s *Scheduler) TransferSource(source, worker string) error { } // 2. check new worker is free and not started relay for another source - stage := w.Stage() - if stage != WorkerFree { + if stage := w.Stage(); stage != WorkerFree { return terror.ErrSchedulerWorkerInvalidTrans.Generate(worker, stage, WorkerBound) } for source2, workers := range s.relayWorkers { @@ -485,13 +484,14 @@ func (s *Scheduler) AddSubTasks(cfgs ...config.SubTaskConfig) error { } taskNames := strMapToSlice(taskNamesM) existSources := strMapToSlice(existSourcesM) - if len(taskNames) > 1 { + switch { + case len(taskNames) > 1: // only subtasks from one task supported now. return terror.ErrSchedulerMultiTask.Generate(taskNames) - } else if len(existSources) == len(cfgs) { + case len(existSources) == len(cfgs): // all subtasks already exist, return an error. return terror.ErrSchedulerSubTaskExist.Generate(taskNames[0], existSources) - } else if len(existSources) > 0 { + case len(existSources) > 0: // some subtasks already exists, log a warn. s.logger.Warn("some subtasks already exist", zap.String("task", taskNames[0]), zap.Strings("sources", existSources)) } @@ -635,7 +635,7 @@ func (s *Scheduler) GetSubTaskCfgsByTask(task string) map[string]*config.SubTask return cloneM } -// GetSubTaskCfgs gets all subconfig, return nil when error happens +// GetSubTaskCfgs gets all subconfig, return nil when error happens. func (s *Scheduler) GetSubTaskCfgs() map[string]map[string]config.SubTaskConfig { s.mu.RLock() defer s.mu.RUnlock() @@ -772,7 +772,7 @@ func (s *Scheduler) UnboundSources() []string { return IDs } -// StartRelay puts etcd key-value pairs to start relay on some workers +// StartRelay puts etcd key-value pairs to start relay on some workers. func (s *Scheduler) StartRelay(source string, workers []string) error { s.mu.Lock() defer s.mu.Unlock() @@ -867,7 +867,7 @@ func (s *Scheduler) StartRelay(source string, workers []string) error { return nil } -// StopRelay deletes etcd key-value pairs to stop relay on some workers +// StopRelay deletes etcd key-value pairs to stop relay on some workers. func (s *Scheduler) StopRelay(source string, workers []string) error { s.mu.Lock() defer s.mu.Unlock() @@ -932,7 +932,7 @@ func (s *Scheduler) StopRelay(source string, workers []string) error { return nil } -// GetRelayWorkers returns all alive worker instances for a relay source +// GetRelayWorkers returns all alive worker instances for a relay source. func (s *Scheduler) GetRelayWorkers(source string) ([]*Worker, error) { s.mu.RLock() defer s.mu.RUnlock() @@ -942,7 +942,7 @@ func (s *Scheduler) GetRelayWorkers(source string) ([]*Worker, error) { } workers := s.relayWorkers[source] - var ret []*Worker + ret := make([]*Worker, 0, len(workers)) for w := range workers { worker, ok := s.workers[w] if !ok { @@ -1162,7 +1162,7 @@ func (s *Scheduler) recoverSubTasks(cli *clientv3.Client) error { // get all subtask stages. stageMM, _, err := ha.GetAllSubTaskStage(cli) if err != nil { - return nil + return err } // recover in-memory data. @@ -1265,7 +1265,7 @@ func (s *Scheduler) recoverWorkersBounds(cli *clientv3.Client) (int64, error) { if len(boundsToTrigger) > 0 { _, err = ha.PutSourceBound(cli, boundsToTrigger...) if err != nil { - return 0, nil + return 0, err } } @@ -1563,7 +1563,7 @@ func (s *Scheduler) tryBoundForWorker(w *Worker) (bounded bool, err error) { // tryBoundForSource tries to bound a source to a random Free worker. // returns (true, nil) after bounded. -// called should update the s.unbounds +// called should update the s.unbounds. func (s *Scheduler) tryBoundForSource(source string) (bool, error) { var worker *Worker relayWorkers := s.relayWorkers[source] @@ -1702,10 +1702,9 @@ func (s *Scheduler) deleteWorker(name string) { // - update the stage of worker to `Bound`. // - record the bound relationship and last bound relationship in the scheduler. // this func is called after the bound relationship existed in etcd. -// TODO: we could only let updateStatusForBound and updateStatusForUnbound to update s.unbounds/bounds/lastBound +// TODO: we could only let updateStatusForBound and updateStatusForUnbound to update s.unbounds/bounds/lastBound. func (s *Scheduler) updateStatusForBound(w *Worker, b ha.SourceBound) error { - err := w.ToBound(b) - if err != nil { + if err := w.ToBound(b); err != nil { return err } s.bounds[b.Source] = w @@ -1747,7 +1746,7 @@ func strMapToSlice(m map[string]struct{}) []string { return ret } -// SetWorkerClientForTest sets mockWorkerClient for specified worker, only used for test +// SetWorkerClientForTest sets mockWorkerClient for specified worker, only used for test. func (s *Scheduler) SetWorkerClientForTest(name string, mockCli workerrpc.Client) { if _, ok := s.workers[name]; ok { s.workers[name].cli = mockCli diff --git a/dm/master/scheduler/scheduler_test.go b/dm/master/scheduler/scheduler_test.go index 268d820b0b..55973c757b 100644 --- a/dm/master/scheduler/scheduler_test.go +++ b/dm/master/scheduler/scheduler_test.go @@ -74,9 +74,7 @@ type testScheduler struct{} var _ = Suite(&testScheduler{}) -var ( - stageEmpty ha.Stage -) +var stageEmpty ha.Stage func (t *testScheduler) TestScheduler(c *C) { t.testSchedulerProgress(c, noRestart) diff --git a/dm/master/scheduler/worker_test.go b/dm/master/scheduler/worker_test.go index e698b675ac..cbae32b0c0 100644 --- a/dm/master/scheduler/worker_test.go +++ b/dm/master/scheduler/worker_test.go @@ -26,8 +26,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -type testWorker struct { -} +type testWorker struct{} var _ = Suite(&testWorker{}) diff --git a/dm/master/server.go b/dm/master/server.go index 0bbb167a85..06d2086046 100644 --- a/dm/master/server.go +++ b/dm/master/server.go @@ -64,27 +64,27 @@ const ( // DM-master cluster : etcd cluster = 1 : 1 now. electionKey = "/dm-master/leader" - // getLeaderBlockTime is the max block time for get leader information from election + // getLeaderBlockTime is the max block time for get leader information from election. getLeaderBlockTime = 10 * time.Minute ) var ( - // the retry times for dm-master to confirm the dm-workers status is expected + // the retry times for dm-master to confirm the dm-workers status is expected. maxRetryNum = 30 - // the retry interval for dm-master to confirm the dm-workers status is expected + // the retry interval for dm-master to confirm the dm-workers status is expected. retryInterval = time.Second // 0 means not use tls - // 1 means use tls + // 1 means use tls. useTLS = int32(0) // typically there's only one server running in one process, but testMaster.TestOfflineMember starts 3 servers, - // so we need sync.Once to prevent data race + // so we need sync.Once to prevent data race. registerOnce sync.Once runBackgroundOnce sync.Once ) -// Server handles RPC requests for dm-master +// Server handles RPC requests for dm-master. type Server struct { sync.RWMutex @@ -105,9 +105,6 @@ type Server struct { // removeMetaLock locks start task when removing meta removeMetaLock sync.RWMutex - // WaitGroup for background functions. - bgFunWg sync.WaitGroup - // dm-worker-ID(host:ip) -> dm-worker client management scheduler *scheduler.Scheduler @@ -119,10 +116,13 @@ type Server struct { // agent pool ap *AgentPool + // WaitGroup for background functions. + bgFunWg sync.WaitGroup + closed sync2.AtomicBool } -// NewServer creates a new Server +// NewServer creates a new Server. func NewServer(cfg *Config) *Server { logger := log.L() server := Server{ @@ -139,7 +139,7 @@ func NewServer(cfg *Config) *Server { return &server } -// Start starts to serving +// Start starts to serving. func (s *Server) Start(ctx context.Context) (err error) { etcdCfg := genEmbedEtcdConfigWithLogger(s.cfg.LogLevel) // prepare config to join an existing cluster @@ -246,10 +246,10 @@ func (s *Server) Start(ctx context.Context) (err error) { }) log.L().Info("listening gRPC API and status request", zap.String("address", s.cfg.MasterAddr)) - return + return nil } -// Close close the RPC server, this function can be called multiple times +// Close close the RPC server, this function can be called multiple times. func (s *Server) Close() { if s.closed.Get() { return @@ -304,6 +304,7 @@ func (s *Server) RegisterWorker(ctx context.Context, req *pb.RegisterWorkerReque err := s.scheduler.AddWorker(req.Name, req.Address) if err != nil { + // nolint:nilerr return &pb.RegisterWorkerResponse{ Result: false, Msg: err.Error(), @@ -330,23 +331,26 @@ func (s *Server) OfflineMember(ctx context.Context, req *pb.OfflineMemberRequest return resp2, err2 } - if req.Type == common.Worker { + switch req.Type { + case common.Worker: err := s.scheduler.RemoveWorker(req.Name) if err != nil { + // nolint:nilerr return &pb.OfflineMemberResponse{ Result: false, Msg: err.Error(), }, nil } - } else if req.Type == common.Master { + case common.Master: err := s.deleteMasterByName(ctx, req.Name) if err != nil { + // nolint:nilerr return &pb.OfflineMemberResponse{ Result: false, Msg: err.Error(), }, nil } - } else { + default: return &pb.OfflineMemberResponse{ Result: false, Msg: terror.ErrMasterInvalidOfflineType.Generate(req.Type).Error(), @@ -393,7 +397,7 @@ func subtaskCfgPointersToInstances(stCfgPointers ...*config.SubTaskConfig) []con return stCfgs } -// StartTask implements MasterServer.StartTask +// StartTask implements MasterServer.StartTask. func (s *Server) StartTask(ctx context.Context, req *pb.StartTaskRequest) (*pb.StartTaskResponse, error) { var ( resp2 *pb.StartTaskResponse @@ -408,6 +412,7 @@ func (s *Server) StartTask(ctx context.Context, req *pb.StartTaskRequest) (*pb.S cfg, stCfgs, err := s.generateSubTask(ctx, req.Task) if err != nil { resp.Msg = err.Error() + // nolint:nilerr return resp, nil } log.L().Info("", zap.String("task name", cfg.Name), zap.String("task", cfg.JSON()), zap.String("request", "StartTask")) @@ -457,6 +462,7 @@ func (s *Server) StartTask(ctx context.Context, req *pb.StartTaskRequest) (*pb.S s.removeMetaLock.Unlock() if err != nil { resp.Msg = err.Error() + // nolint:nilerr return resp, nil } @@ -471,7 +477,7 @@ func (s *Server) StartTask(ctx context.Context, req *pb.StartTaskRequest) (*pb.S return resp, nil } -// OperateTask implements MasterServer.OperateTask +// OperateTask implements MasterServer.OperateTask. func (s *Server) OperateTask(ctx context.Context, req *pb.OperateTaskRequest) (*pb.OperateTaskResponse, error) { var ( resp2 *pb.OperateTaskResponse @@ -515,6 +521,7 @@ func (s *Server) OperateTask(ctx context.Context, req *pb.OperateTaskRequest) (* } if err != nil { resp.Msg = err.Error() + // nolint:nilerr return resp, nil } @@ -523,7 +530,7 @@ func (s *Server) OperateTask(ctx context.Context, req *pb.OperateTaskRequest) (* return resp, nil } -// GetSubTaskCfg implements MasterServer.GetSubTaskCfg +// GetSubTaskCfg implements MasterServer.GetSubTaskCfg. func (s *Server) GetSubTaskCfg(ctx context.Context, req *pb.GetSubTaskCfgRequest) (*pb.GetSubTaskCfgResponse, error) { var ( resp2 *pb.GetSubTaskCfgResponse @@ -547,6 +554,7 @@ func (s *Server) GetSubTaskCfg(ctx context.Context, req *pb.GetSubTaskCfgRequest for _, cfg := range subCfgs { cfgBytes, err := cfg.Toml() if err != nil { + // nolint:nilerr return &pb.GetSubTaskCfgResponse{ Result: false, Msg: err.Error(), @@ -562,7 +570,7 @@ func (s *Server) GetSubTaskCfg(ctx context.Context, req *pb.GetSubTaskCfgRequest } // UpdateTask implements MasterServer.UpdateTask -// TODO: support update task later +// TODO: support update task later. func (s *Server) UpdateTask(ctx context.Context, req *pb.UpdateTaskRequest) (*pb.UpdateTaskResponse, error) { var ( resp2 *pb.UpdateTaskResponse @@ -575,6 +583,7 @@ func (s *Server) UpdateTask(ctx context.Context, req *pb.UpdateTaskRequest) (*pb cfg, stCfgs, err := s.generateSubTask(ctx, req.Task) if err != nil { + // nolint:nilerr return &pb.UpdateTaskResponse{ Result: false, Msg: err.Error(), @@ -632,7 +641,8 @@ type hasWokers interface { func extractSources(s *Server, req hasWokers) ([]string, error) { var sources []string - if len(req.GetSources()) > 0 { + switch { + case len(req.GetSources()) > 0: sources = req.GetSources() var invalidSource []string for _, source := range sources { @@ -643,13 +653,13 @@ func extractSources(s *Server, req hasWokers) ([]string, error) { if len(invalidSource) > 0 { return nil, errors.Errorf("sources %s haven't been added", invalidSource) } - } else if len(req.GetName()) > 0 { + case len(req.GetName()) > 0: // query specified task's sources sources = s.getTaskResources(req.GetName()) if len(sources) == 0 { return nil, errors.Errorf("task %s has no source or not exist", req.GetName()) } - } else { + default: // query all sources log.L().Info("get sources") sources = s.scheduler.BoundSources() @@ -657,7 +667,7 @@ func extractSources(s *Server, req hasWokers) ([]string, error) { return sources, nil } -// QueryStatus implements MasterServer.QueryStatus +// QueryStatus implements MasterServer.QueryStatus. func (s *Server) QueryStatus(ctx context.Context, req *pb.QueryStatusListRequest) (*pb.QueryStatusListResponse, error) { var ( resp2 *pb.QueryStatusListResponse @@ -670,6 +680,7 @@ func (s *Server) QueryStatus(ctx context.Context, req *pb.QueryStatusListRequest sources, err := extractSources(s, req) if err != nil { + // nolint:nilerr return &pb.QueryStatusListResponse{ Result: false, Msg: err.Error(), @@ -701,7 +712,7 @@ func (s *Server) QueryStatus(ctx context.Context, req *pb.QueryStatusListRequest return resp, nil } -// ShowDDLLocks implements MasterServer.ShowDDLLocks +// ShowDDLLocks implements MasterServer.ShowDDLLocks. func (s *Server) ShowDDLLocks(ctx context.Context, req *pb.ShowDDLLocksRequest) (*pb.ShowDDLLocksResponse, error) { var ( resp2 *pb.ShowDDLLocksResponse @@ -771,7 +782,7 @@ func (s *Server) UnlockDDLLock(ctx context.Context, req *pb.UnlockDDLLockRequest return resp, nil } -// PurgeWorkerRelay implements MasterServer.PurgeWorkerRelay +// PurgeWorkerRelay implements MasterServer.PurgeWorkerRelay. func (s *Server) PurgeWorkerRelay(ctx context.Context, req *pb.PurgeWorkerRelayRequest) (*pb.PurgeWorkerRelayResponse, error) { var ( resp2 *pb.PurgeWorkerRelayResponse @@ -851,7 +862,7 @@ func (s *Server) PurgeWorkerRelay(ctx context.Context, req *pb.PurgeWorkerRelayR }, nil } -// OperateWorkerRelayTask implements MasterServer.OperateWorkerRelayTask +// OperateWorkerRelayTask implements MasterServer.OperateWorkerRelayTask. func (s *Server) OperateWorkerRelayTask(ctx context.Context, req *pb.OperateWorkerRelayRequest) (*pb.OperateWorkerRelayResponse, error) { var ( resp2 *pb.OperateWorkerRelayResponse @@ -879,6 +890,7 @@ func (s *Server) OperateWorkerRelayTask(ctx context.Context, req *pb.OperateWork err := s.scheduler.UpdateExpectRelayStage(expect, req.Sources...) if err != nil { resp.Msg = err.Error() + // nolint:nilerr return resp, nil } resp.Result = true @@ -886,7 +898,7 @@ func (s *Server) OperateWorkerRelayTask(ctx context.Context, req *pb.OperateWork return resp, nil } -// getTaskResources gets workers relevant to specified task +// getTaskResources gets workers relevant to specified task. func (s *Server) getTaskResources(task string) []string { s.Lock() defer s.Unlock() @@ -899,7 +911,7 @@ func (s *Server) getTaskResources(task string) []string { return ret } -// getStatusFromWorkers does RPC request to get status from dm-workers +// getStatusFromWorkers does RPC request to get status from dm-workers. func (s *Server) getStatusFromWorkers(ctx context.Context, sources []string, taskName string, relayWorker bool) []*pb.QueryStatusResponse { workerReq := &workerrpc.Request{ Type: workerrpc.CmdQueryStatus, @@ -1000,8 +1012,8 @@ func (s *Server) getStatusFromWorkers(ctx context.Context, sources []string, tas return workerResps } -// TODO: refine the call stack of this API, query worker configs that we needed only -func (s *Server) getSourceConfigs(sources []*config.MySQLInstance) (map[string]config.DBConfig, error) { +// TODO: refine the call stack of this API, query worker configs that we needed only. +func (s *Server) getSourceConfigs(sources []*config.MySQLInstance) map[string]config.DBConfig { cfgs := make(map[string]config.DBConfig) for _, source := range sources { if cfg := s.scheduler.GetSourceCfgByID(source.SourceID); cfg != nil { @@ -1010,10 +1022,10 @@ func (s *Server) getSourceConfigs(sources []*config.MySQLInstance) (map[string]c cfgs[source.SourceID] = cfg.From } } - return cfgs, nil + return cfgs } -// CheckTask checks legality of task configuration +// CheckTask checks legality of task configuration. func (s *Server) CheckTask(ctx context.Context, req *pb.CheckTaskRequest) (*pb.CheckTaskResponse, error) { var ( resp2 *pb.CheckTaskResponse @@ -1026,6 +1038,7 @@ func (s *Server) CheckTask(ctx context.Context, req *pb.CheckTaskRequest) (*pb.C _, _, err := s.generateSubTask(ctx, req.Task) if err != nil { + // nolint:nilerr return &pb.CheckTaskResponse{ Result: false, Msg: err.Error(), @@ -1115,6 +1128,7 @@ func (s *Server) OperateSource(ctx context.Context, req *pb.OperateSourceRequest } if err != nil { resp.Msg = err.Error() + // nolint:nilerr return resp, nil } @@ -1179,6 +1193,7 @@ func (s *Server) OperateSource(ctx context.Context, req *pb.OperateSourceRequest // or give a command to show existing source id if err3 != nil { resp.Msg = err3.Error() + // nolint:nilerr return resp, nil } } @@ -1231,7 +1246,7 @@ func (s *Server) OperateSource(ctx context.Context, req *pb.OperateSourceRequest } // OperateLeader implements MasterServer.OperateLeader -// Note: this request doesn't need to forward to leader +// Note: this request doesn't need to forward to leader. func (s *Server) OperateLeader(ctx context.Context, req *pb.OperateLeaderRequest) (*pb.OperateLeaderResponse, error) { log.L().Info("", zap.Stringer("payload", req), zap.String("request", "OperateLeader")) @@ -1264,10 +1279,7 @@ func (s *Server) generateSubTask(ctx context.Context, task string) (*config.Task return nil, nil, terror.WithClass(err, terror.ClassDMMaster) } - sourceCfgs, err := s.getSourceConfigs(cfg.MySQLInstances) - if err != nil { - return nil, nil, err - } + sourceCfgs := s.getSourceConfigs(cfg.MySQLInstances) stCfgs, err := cfg.SubTaskConfigs(sourceCfgs) if err != nil { @@ -1288,7 +1300,6 @@ func setUseTLS(tlsCfg *config.Security) { } else { atomic.StoreInt32(&useTLS, 0) } - } func enableTLS(tlsCfg *config.Security) bool { @@ -1392,7 +1403,7 @@ Relay: OperateRelay: * pause: related relay status is paused * resume: related relay status is running -In the above situations, once we find an error in response we should return the error +In the above situations, once we find an error in response we should return the error. */ func (s *Server) waitOperationOk(ctx context.Context, cli *scheduler.Worker, taskName, sourceID string, masterReq interface{}) (*pb.QueryStatusResponse, error) { var expect pb.Stage @@ -1588,7 +1599,6 @@ func (s *Server) getSourceRespsAfterOperation(ctx context.Context, taskName stri } func (s *Server) listMemberMaster(ctx context.Context, names []string) (*pb.Members_Master, error) { - resp := &pb.Members_Master{ Master: &pb.ListMasterMember{}, } @@ -1596,6 +1606,7 @@ func (s *Server) listMemberMaster(ctx context.Context, names []string) (*pb.Memb memberList, err := s.etcdClient.MemberList(ctx) if err != nil { resp.Master.Msg = err.Error() + // nolint:nilerr return resp, nil } @@ -1627,6 +1638,7 @@ func (s *Server) listMemberMaster(ctx context.Context, names []string) (*pb.Memb if len(etcdMember.ClientURLs) == 0 { alive = false } else { + // nolint:noctx, bodyclose _, err := client.Get(etcdMember.ClientURLs[0] + "/health") if err != nil { alive = false @@ -1649,7 +1661,7 @@ func (s *Server) listMemberMaster(ctx context.Context, names []string) (*pb.Memb return resp, nil } -func (s *Server) listMemberWorker(ctx context.Context, names []string) (*pb.Members_Worker, error) { +func (s *Server) listMemberWorker(names []string) *pb.Members_Worker { resp := &pb.Members_Worker{ Worker: &pb.ListWorkerMember{}, } @@ -1657,7 +1669,7 @@ func (s *Server) listMemberWorker(ctx context.Context, names []string) (*pb.Memb workerAgents, err := s.scheduler.GetAllWorkers() if err != nil { resp.Worker.Msg = err.Error() - return resp, nil + return resp } all := len(names) == 0 @@ -1685,10 +1697,10 @@ func (s *Server) listMemberWorker(ctx context.Context, names []string) (*pb.Memb return workers[lhs].Name < workers[rhs].Name }) resp.Worker.Workers = workers - return resp, nil + return resp } -func (s *Server) listMemberLeader(ctx context.Context, names []string) (*pb.Members_Leader, error) { +func (s *Server) listMemberLeader(ctx context.Context, names []string) *pb.Members_Leader { resp := &pb.Members_Leader{ Leader: &pb.ListLeaderMember{}, } @@ -1702,19 +1714,19 @@ func (s *Server) listMemberLeader(ctx context.Context, names []string) (*pb.Memb _, name, addr, err := s.election.LeaderInfo(ctx) if err != nil { resp.Leader.Msg = err.Error() - return resp, nil + return resp } if !all && !set[name] { - return resp, nil + return resp } resp.Leader.Name = name resp.Leader.Addr = addr - return resp, nil + return resp } -// ListMember list member information +// ListMember list member information. func (s *Server) ListMember(ctx context.Context, req *pb.ListMemberRequest) (*pb.ListMemberResponse, error) { var ( resp2 *pb.ListMemberResponse @@ -1735,11 +1747,7 @@ func (s *Server) ListMember(ctx context.Context, req *pb.ListMemberRequest) (*pb members := make([]*pb.Members, 0) if req.Leader { - res, err := s.listMemberLeader(ctx, req.Names) - if err != nil { - resp.Msg = err.Error() - return resp, nil - } + res := s.listMemberLeader(ctx, req.Names) members = append(members, &pb.Members{ Member: res, }) @@ -1749,6 +1757,7 @@ func (s *Server) ListMember(ctx context.Context, req *pb.ListMemberRequest) (*pb res, err := s.listMemberMaster(ctx, req.Names) if err != nil { resp.Msg = err.Error() + // nolint:nilerr return resp, nil } members = append(members, &pb.Members{ @@ -1757,11 +1766,7 @@ func (s *Server) ListMember(ctx context.Context, req *pb.ListMemberRequest) (*pb } if req.Worker { - res, err := s.listMemberWorker(ctx, req.Names) - if err != nil { - resp.Msg = err.Error() - return resp, nil - } + res := s.listMemberWorker(req.Names) members = append(members, &pb.Members{ Member: res, }) @@ -1882,7 +1887,7 @@ func (s *Server) createMasterClientByName(ctx context.Context, name string) (pb. return nil, err } -// GetMasterCfg implements MasterServer.GetMasterCfg +// GetMasterCfg implements MasterServer.GetMasterCfg. func (s *Server) GetMasterCfg(ctx context.Context, req *pb.GetMasterCfgRequest) (*pb.GetMasterCfgResponse, error) { log.L().Info("", zap.Any("payload", req), zap.String("request", "GetMasterCfg")) @@ -1892,7 +1897,7 @@ func (s *Server) GetMasterCfg(ctx context.Context, req *pb.GetMasterCfgRequest) return resp, err } -// GetCfg implements MasterServer.GetCfg +// GetCfg implements MasterServer.GetCfg. func (s *Server) GetCfg(ctx context.Context, req *pb.GetCfgRequest) (*pb.GetCfgResponse, error) { var ( resp2 = &pb.GetCfgResponse{} @@ -1937,11 +1942,13 @@ func (s *Server) GetCfg(ctx context.Context, req *pb.GetCfgRequest) (*pb.GetCfgR masterClient, err := s.createMasterClientByName(ctx, req.Name) if err != nil { resp2.Msg = err.Error() + // nolint:nilerr return resp2, nil } masterResp, err := masterClient.GetMasterCfg(ctx, &pb.GetMasterCfgRequest{}) if err != nil { resp2.Msg = err.Error() + // nolint:nilerr return resp2, nil } cfg = masterResp.Cfg @@ -1958,6 +1965,7 @@ func (s *Server) GetCfg(ctx context.Context, req *pb.GetCfgRequest) (*pb.GetCfgR workerResp, err := worker.SendRequest(ctx, &workerReq, s.cfg.RPCTimeout) if err != nil { resp2.Msg = err.Error() + // nolint:nilerr return resp2, nil } cfg = workerResp.GetWorkerCfg.Cfg @@ -1965,12 +1973,14 @@ func (s *Server) GetCfg(ctx context.Context, req *pb.GetCfgRequest) (*pb.GetCfgR sourceCfg := s.scheduler.GetSourceCfgByID(req.Name) if sourceCfg == nil { resp2.Msg = "source not found" + return resp2, nil } sourceCfg.From.Password = "******" cfg, err2 = sourceCfg.Yaml() if err2 != nil { resp2.Msg = err2.Error() + // nolint:nilerr return resp2, nil } default: @@ -1984,7 +1994,7 @@ func (s *Server) GetCfg(ctx context.Context, req *pb.GetCfgRequest) (*pb.GetCfgR }, nil } -// HandleError implements MasterServer.HandleError +// HandleError implements MasterServer.HandleError. func (s *Server) HandleError(ctx context.Context, req *pb.HandleErrorRequest) (*pb.HandleErrorResponse, error) { var ( resp2 *pb.HandleErrorResponse @@ -2057,7 +2067,7 @@ func (s *Server) HandleError(ctx context.Context, req *pb.HandleErrorRequest) (* }, nil } -// TransferSource implements MasterServer.TransferSource +// TransferSource implements MasterServer.TransferSource. func (s *Server) TransferSource(ctx context.Context, req *pb.TransferSourceRequest) (*pb.TransferSourceResponse, error) { var ( resp2 = &pb.TransferSourceResponse{} @@ -2071,13 +2081,14 @@ func (s *Server) TransferSource(ctx context.Context, req *pb.TransferSourceReque err := s.scheduler.TransferSource(req.Source, req.Worker) if err != nil { resp2.Msg = err.Error() + // nolint:nilerr return resp2, nil } resp2.Result = true return resp2, nil } -// OperateRelay implements MasterServer.OperateRelay +// OperateRelay implements MasterServer.OperateRelay. func (s *Server) OperateRelay(ctx context.Context, req *pb.OperateRelayRequest) (*pb.OperateRelayResponse, error) { var ( resp2 = &pb.OperateRelayResponse{} @@ -2099,6 +2110,7 @@ func (s *Server) OperateRelay(ctx context.Context, req *pb.OperateRelayRequest) } if err != nil { resp2.Msg = err.Error() + // nolint:nilerr return resp2, nil } resp2.Result = true @@ -2107,8 +2119,9 @@ func (s *Server) OperateRelay(ctx context.Context, req *pb.OperateRelayRequest) // sharedLogic does some shared logic for each RPC implementation // arguments with `Pointer` suffix should be pointer to that variable its name indicated -// return `true` means caller should return with variable that `xxPointer` modified +// return `true` means caller should return with variable that `xxPointer` modified. func (s *Server) sharedLogic(ctx context.Context, req interface{}, respPointer interface{}, errPointer *error) bool { + // nolint:dogsled pc, _, _, _ := runtime.Caller(1) fullMethodName := runtime.FuncForPC(pc).Name() methodName := fullMethodName[strings.LastIndexByte(fullMethodName, '.')+1:] diff --git a/dm/master/server_test.go b/dm/master/server_test.go index 16ee1e8497..851289cd30 100644 --- a/dm/master/server_test.go +++ b/dm/master/server_test.go @@ -60,7 +60,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// use task config from integration test `sharding` +// use task config from integration test `sharding`. var taskConfig = `--- name: test task-mode: all @@ -275,8 +275,9 @@ func testMockScheduler(ctx context.Context, wg *sync.WaitGroup, c *check.C, sour defer wg.Done() c.Assert(ha.KeepAlive(ctx, etcdTestCli, workerName, keepAliveTTL), check.IsNil) }(ctx1, name) + idx := i c.Assert(utils.WaitSomething(30, 100*time.Millisecond, func() bool { - w := scheduler2.GetWorkerBySource(sources[i]) + w := scheduler2.GetWorkerBySource(sources[idx]) return w != nil && w.BaseInfo().Name == name }), check.IsTrue) } @@ -308,8 +309,9 @@ func testMockSchedulerForRelay(ctx context.Context, wg *sync.WaitGroup, c *check c.Assert(ha.KeepAlive(ctx, etcdTestCli, workerName, keepAliveTTL), check.IsNil) }(ctx1, name) c.Assert(scheduler2.StartRelay(sources[i], []string{workers[i]}), check.IsNil) + idx := i c.Assert(utils.WaitSomething(30, 100*time.Millisecond, func() bool { - relayWorkers, err2 := scheduler2.GetRelayWorkers(sources[i]) + relayWorkers, err2 := scheduler2.GetRelayWorkers(sources[idx]) c.Assert(err2, check.IsNil) return len(relayWorkers) == 1 && relayWorkers[0].BaseInfo().Name == name }), check.IsTrue) @@ -323,6 +325,7 @@ func (t *testMaster) TestQueryStatus(c *check.C) { server := testDefaultMasterServer(c) sources, workers := defaultWorkerSource() + var cancels []context.CancelFunc // test query all workers for _, worker := range workers { @@ -338,7 +341,10 @@ func (t *testMaster) TestQueryStatus(c *check.C) { } var wg sync.WaitGroup ctx, cancel := context.WithCancel(context.Background()) - server.scheduler, _ = testMockScheduler(ctx, &wg, c, sources, workers, "", t.workerClients) + server.scheduler, cancels = testMockScheduler(ctx, &wg, c, sources, workers, "", t.workerClients) + for _, cancelFunc := range cancels { + defer cancelFunc() + } resp, err := server.QueryStatus(context.Background(), &pb.QueryStatusListRequest{}) c.Assert(err, check.IsNil) c.Assert(resp.Result, check.IsTrue) @@ -357,7 +363,10 @@ func (t *testMaster) TestQueryStatus(c *check.C) { t.workerClients[worker] = newMockRPCClient(mockWorkerClient) } ctx, cancel = context.WithCancel(context.Background()) - server.scheduler, _ = testMockSchedulerForRelay(ctx, &wg, c, sources, workers, "", t.workerClients) + server.scheduler, cancels = testMockSchedulerForRelay(ctx, &wg, c, sources, workers, "passwd", t.workerClients) + for _, cancelFunc := range cancels { + defer cancelFunc() + } resp, err = server.QueryStatus(context.Background(), &pb.QueryStatusListRequest{ Sources: sources, }) @@ -508,15 +517,16 @@ func (t *testMaster) TestStartTask(c *check.C) { } // db use for remove data -// verDB user for show version +// verDB user for show version. type mockDBProvider struct { verDB *sql.DB db *sql.DB } -// return db if verDB was closed +// return db if verDB was closed. func (d *mockDBProvider) Apply(config config.DBConfig) (*conn.BaseDB, error) { if err := d.verDB.Ping(); err != nil { + // nolint:nilerr return conn.NewBaseDB(d.db, func() {}), nil } return conn.NewBaseDB(d.verDB, func() {}), nil @@ -990,7 +1000,7 @@ func (t *testMaster) TestServer(c *check.C) { t.testHTTPInterface(c, fmt.Sprintf("http://%s/status", cfg.MasterAddr), []byte(utils.GetRawInfo())) t.testHTTPInterface(c, fmt.Sprintf("http://%s/debug/pprof/", cfg.MasterAddr), []byte("Types of profiles available")) // HTTP API in this unit test is unstable, but we test it in `http_apis` in integration test. - //t.testHTTPInterface(c, fmt.Sprintf("http://%s/apis/v1alpha1/status/test-task", cfg.MasterAddr), []byte("task test-task has no source or not exist")) + // t.testHTTPInterface(c, fmt.Sprintf("http://%s/apis/v1alpha1/status/test-task", cfg.MasterAddr), []byte("task test-task has no source or not exist")) dupServer := NewServer(cfg) err := dupServer.Start(ctx) @@ -1183,6 +1193,7 @@ func (t *testMaster) testHTTPInterface(c *check.C, url string, contain []byte) { c.Assert(err, check.IsNil) cli := toolutils.ClientWithTLS(tls.TLSConfig()) + // nolint:noctx resp, err := cli.Get(url) c.Assert(err, check.IsNil) defer resp.Body.Close() @@ -1810,8 +1821,7 @@ func createTableInfo(c *check.C, p *parser.Parser, se sessionctx.Context, tableI return info } -type testEtcd struct { -} +type testEtcd struct{} var _ = check.Suite(&testEtcd{}) diff --git a/dm/master/shardddl/info.go b/dm/master/shardddl/info.go index d493ea066a..e7cd302e8c 100644 --- a/dm/master/shardddl/info.go +++ b/dm/master/shardddl/info.go @@ -40,7 +40,7 @@ func (p PessimismInfoSlice) Swap(i, j int) { // pessimismInfoMapToSlice converts a `map[string]pessimism.Info` to `[]pessimism.Info` in increasing order according to `Source` field. func pessimismInfoMapToSlice(ifm map[string]pessimism.Info) []pessimism.Info { - var ret PessimismInfoSlice + ret := make(PessimismInfoSlice, 0, len(ifm)) for _, info := range ifm { ret = append(ret, info) } diff --git a/dm/master/shardddl/optimist.go b/dm/master/shardddl/optimist.go index d821a00033..9bad67eec0 100644 --- a/dm/master/shardddl/optimist.go +++ b/dm/master/shardddl/optimist.go @@ -163,7 +163,7 @@ func (o *Optimist) ShowLocks(task string, sources []string) []*pb.DDLLock { } // RemoveMetaData removes meta data for a specified task -// NOTE: this function can only be used when the specified task is not running +// NOTE: this function can only be used when the specified task is not running. func (o *Optimist) RemoveMetaData(task string) error { o.mu.Lock() defer o.mu.Unlock() @@ -274,7 +274,7 @@ func (o *Optimist) rebuildLocks() (revSource, revInfo, revOperation int64, err e return revSource, revInfo, revOperation, nil } -// sortInfos sort all infos by revision +// sortInfos sort all infos by revision. func sortInfos(ifm map[string]map[string]map[string]map[string]optimism.Info) []optimism.Info { infos := make([]optimism.Info, 0, len(ifm)) @@ -295,13 +295,12 @@ func sortInfos(ifm map[string]map[string]map[string]map[string]optimism.Info) [] return infos } -// buildLockJoinedAndTTS build joined table and target table slice for lock by history infos +// buildLockJoinedAndTTS build joined table and target table slice for lock by history infos. func (o *Optimist) buildLockJoinedAndTTS( ifm map[string]map[string]map[string]map[string]optimism.Info, initSchemas map[string]map[string]map[string]optimism.InitSchema) ( map[string]schemacmp.Table, map[string][]optimism.TargetTable, map[string]map[string]map[string]map[string]schemacmp.Table) { - type infoKey struct { lockID string source string @@ -636,28 +635,30 @@ func (o *Optimist) handleOperationPut(ctx context.Context, opCh <-chan optimism. // handleLock handles a single shard DDL lock. func (o *Optimist) handleLock(info optimism.Info, tts []optimism.TargetTable, skipDone bool) error { lockID, newDDLs, cols, err := o.lk.TrySync(o.cli, info, tts) - var cfStage = optimism.ConflictNone - var cfMsg = "" - if info.IgnoreConflict { + cfStage := optimism.ConflictNone + cfMsg := "" + switch { + case info.IgnoreConflict: o.logger.Warn("error occur when trying to sync for shard DDL info, this often means shard DDL conflict detected", zap.String("lock", lockID), zap.String("info", info.ShortString()), zap.Bool("is deleted", info.IsDeleted), log.ShortError(err)) - } else if err != nil { + case err != nil: cfStage = optimism.ConflictDetected // we treat any errors returned from `TrySync` as conflict detected now. cfMsg = err.Error() o.logger.Warn("error occur when trying to sync for shard DDL info, this often means shard DDL conflict detected", zap.String("lock", lockID), zap.String("info", info.ShortString()), zap.Bool("is deleted", info.IsDeleted), log.ShortError(err)) - } else { + default: o.logger.Info("the shard DDL lock returned some DDLs", zap.String("lock", lockID), zap.Strings("ddls", newDDLs), zap.Strings("cols", cols), zap.String("info", info.ShortString()), zap.Bool("is deleted", info.IsDeleted)) // try to record the init schema before applied the DDL to the downstream. initSchema := optimism.NewInitSchema(info.Task, info.DownSchema, info.DownTable, info.TableInfoBefore) rev, putted, err2 := optimism.PutInitSchemaIfNotExist(o.cli, initSchema) - if err2 != nil { + switch { + case err2 != nil: return err2 - } else if putted { + case putted: o.logger.Info("recorded the initial schema", zap.String("info", info.ShortString())) - } else { + default: o.logger.Debug("skip to record the initial schema", zap.String("info", info.ShortString()), zap.Int64("revision", rev)) } } diff --git a/dm/master/shardddl/optimist_test.go b/dm/master/shardddl/optimist_test.go index 53a02a93c7..184b012da3 100644 --- a/dm/master/shardddl/optimist_test.go +++ b/dm/master/shardddl/optimist_test.go @@ -663,7 +663,7 @@ func (t *testOptimist) TestOptimistLockConflict(c *C) { st1 = optimism.NewSourceTables(task, source1) p = parser.New() se = mock.NewContext() - tblID int64 = 111 + tblID int64 = 222 DDLs1 = []string{"ALTER TABLE bar ADD COLUMN c1 TEXT"} DDLs2 = []string{"ALTER TABLE bar ADD COLUMN c1 DATETIME"} ti0 = createTableInfo(c, p, se, tblID, `CREATE TABLE bar (id INT PRIMARY KEY)`) diff --git a/dm/master/shardddl/pessimist.go b/dm/master/shardddl/pessimist.go index d47eb69e44..901ad4935f 100644 --- a/dm/master/shardddl/pessimist.go +++ b/dm/master/shardddl/pessimist.go @@ -22,6 +22,8 @@ import ( "go.etcd.io/etcd/clientv3" "go.uber.org/zap" + "github.com/pingcap/failpoint" + "github.com/pingcap/dm/dm/config" "github.com/pingcap/dm/dm/master/metrics" "github.com/pingcap/dm/dm/pb" @@ -29,7 +31,6 @@ import ( "github.com/pingcap/dm/pkg/log" "github.com/pingcap/dm/pkg/shardddl/pessimism" "github.com/pingcap/dm/pkg/terror" - "github.com/pingcap/failpoint" ) var ( @@ -276,16 +277,16 @@ func (p *Pessimist) ShowLocks(task string, sources []string) []*pb.DDLLock { // if specified forceRemove and then fail to unlock, we may need to use `BreakLock` later. // NOTE: this function has side effects, if it failed, some status can't revert anymore. // NOTE: this function should not be called if the lock is still in automatic resolving. -func (p *Pessimist) UnlockLock(ctx context.Context, ID, replaceOwner string, forceRemove bool) error { +func (p *Pessimist) UnlockLock(ctx context.Context, id, replaceOwner string, forceRemove bool) error { p.mu.Lock() defer p.mu.Unlock() if p.closed { return terror.ErrMasterPessimistNotStarted.Generate() } // 1. find the lock. - lock := p.lk.FindLock(ID) + lock := p.lk.FindLock(id) if lock == nil { - return terror.ErrMasterLockNotFound.Generate(ID) + return terror.ErrMasterLockNotFound.Generate(id) } // 2. check whether has resolved before (this often should not happen). @@ -294,7 +295,7 @@ func (p *Pessimist) UnlockLock(ctx context.Context, ID, replaceOwner string, for if err != nil { return err } - return terror.ErrMasterLockIsResolving.Generatef("the lock %s has been resolved before", ID) + return terror.ErrMasterLockIsResolving.Generatef("the lock %s has been resolved before", id) } // 3. find out synced & un-synced sources. @@ -317,7 +318,7 @@ func (p *Pessimist) UnlockLock(ctx context.Context, ID, replaceOwner string, for // if no source synced yet, we should choose to use `BreakLock` instead. owner := lock.Owner if replaceOwner != "" { - p.logger.Warn("replace the owner of the lock", zap.String("lock", ID), + p.logger.Warn("replace the owner of the lock", zap.String("lock", id), zap.String("original owner", owner), zap.String("new owner", replaceOwner)) owner = replaceOwner } @@ -344,7 +345,7 @@ func (p *Pessimist) UnlockLock(ctx context.Context, ID, replaceOwner string, for } else if !done && !forceRemove { // if `forceRemove==true`, we still try to complete following steps. revertLockSync = true return terror.ErrMasterOwnerExecDDL.Generatef( - "the owner %s of the lock %s has not done the operation", owner, ID) + "the owner %s of the lock %s has not done the operation", owner, id) } // 7. put `skip` operations for other sources, and wait for them to be done. @@ -353,31 +354,32 @@ func (p *Pessimist) UnlockLock(ctx context.Context, ID, replaceOwner string, for done, err = p.waitNonOwnerToBeDone(ctx, lock, owner, synced) if err != nil { p.logger.Error("the owner has done the exec operation, but fail to wait for some other sources done the skip operation, the lock is still removed", - zap.String("lock", ID), zap.Bool("force remove", forceRemove), zap.String("owner", owner), + zap.String("lock", id), zap.Bool("force remove", forceRemove), zap.String("owner", owner), zap.Strings("un-synced", unsynced), zap.Strings("synced", synced), zap.Error(err)) } else if !done { p.logger.Error("the owner has done the exec operation, but some other sources have not done the skip operation, the lock is still removed", - zap.String("lock", ID), zap.Bool("force remove", forceRemove), zap.String("owner", owner), + zap.String("lock", id), zap.Bool("force remove", forceRemove), zap.String("owner", owner), zap.Strings("un-synced", unsynced), zap.Strings("synced", synced)) } // 8. remove or clear shard DDL lock and info. - p.lk.RemoveLock(ID) + p.lk.RemoveLock(id) err2 := p.deleteInfosOps(lock) - if err != nil && err2 != nil { + switch { + case err != nil && err2 != nil: return terror.ErrMasterPartWorkerExecDDLFail.AnnotateDelegate( err, "fail to wait for non-owner sources %v to skip the shard DDL and delete shard DDL infos and operations, %s", unsynced, err2.Error()) - } else if err != nil { + case err != nil: return terror.ErrMasterPartWorkerExecDDLFail.Delegate(err, "fail to wait for non-owner sources to skip the shard DDL") - } else if err2 != nil { + case err2 != nil: return terror.ErrMasterPartWorkerExecDDLFail.Delegate(err2, "fail to delete shard DDL infos and operations") } return nil } // RemoveMetaData removes meta data for a specified task -// NOTE: this function can only be used when the specified task is not running +// NOTE: this function can only be used when the specified task is not running. func (p *Pessimist) RemoveMetaData(task string) error { p.mu.Lock() defer p.mu.Unlock() @@ -637,8 +639,7 @@ func (p *Pessimist) putOpsForNonOwner(lock *pessimism.Lock, onlySource string, s // removeLock removes the lock in memory and its information in etcd. func (p *Pessimist) removeLock(lock *pessimism.Lock) error { // remove all operations for this shard DDL lock. - err := p.deleteOps(lock) - if err != nil { + if err := p.deleteOps(lock); err != nil { return err } @@ -741,7 +742,6 @@ func (p *Pessimist) waitOwnerToBeDone(ctx context.Context, lock *pessimism.Lock, } p.logger.Info("retry to wait for the owner done the operation", zap.String("owner", owner), zap.String("lock", lock.ID), zap.Int("retry", retryNum)) - } return lock.IsDone(owner), nil @@ -807,7 +807,6 @@ func (p *Pessimist) waitNonOwnerToBeDone(ctx context.Context, lock *pessimism.Lo } p.logger.Info("retry to wait for non-owner sources done the operation", zap.String("lock", lock.ID), zap.Strings("sources", waitSources), zap.Int("retry", retryNum)) - } return allDone(), nil diff --git a/dm/master/workerrpc/interface.go b/dm/master/workerrpc/interface.go index cbda750e2f..d767cfaebb 100644 --- a/dm/master/workerrpc/interface.go +++ b/dm/master/workerrpc/interface.go @@ -89,7 +89,7 @@ type Client interface { Close() error } -// IsStreamAPI checks whether a request is streaming API based on CmdType +// IsStreamAPI checks whether a request is streaming API based on CmdType. func (req *Request) IsStreamAPI() bool { return req.Type == CmdFetchDDLInfo } diff --git a/dm/master/workerrpc/rawgrpc.go b/dm/master/workerrpc/rawgrpc.go index 4b90dcced5..3f7d41a845 100644 --- a/dm/master/workerrpc/rawgrpc.go +++ b/dm/master/workerrpc/rawgrpc.go @@ -27,14 +27,14 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// GRPCClient stores raw grpc connection and worker client +// GRPCClient stores raw grpc connection and worker client. type GRPCClient struct { conn *grpc.ClientConn client pb.WorkerClient closed int32 } -// NewGRPCClientWrap initializes a new grpc client from given grpc connection and worker client +// NewGRPCClientWrap initializes a new grpc client from given grpc connection and worker client. func NewGRPCClientWrap(conn *grpc.ClientConn, client pb.WorkerClient) (*GRPCClient, error) { return &GRPCClient{ conn: conn, @@ -43,7 +43,7 @@ func NewGRPCClientWrap(conn *grpc.ClientConn, client pb.WorkerClient) (*GRPCClie }, nil } -// NewGRPCClient initializes a new grpc client from worker address +// NewGRPCClient initializes a new grpc client from worker address. func NewGRPCClient(addr string, securityCfg config.Security) (*GRPCClient, error) { tls, err := toolutils.NewTLS(securityCfg.SSLCA, securityCfg.SSLCert, securityCfg.SSLKey, addr, securityCfg.CertAllowedCN) if err != nil { @@ -67,7 +67,7 @@ func NewGRPCClient(addr string, securityCfg config.Security) (*GRPCClient, error return NewGRPCClientWrap(conn, pb.NewWorkerClient(conn)) } -// SendRequest implements Client.SendRequest +// SendRequest implements Client.SendRequest. func (c *GRPCClient) SendRequest(ctx context.Context, req *Request, timeout time.Duration) (*Response, error) { if atomic.LoadInt32(&c.closed) != 0 { return nil, terror.ErrMasterGRPCSendOnCloseConn.Generate() @@ -82,7 +82,7 @@ func (c *GRPCClient) SendRequest(ctx context.Context, req *Request, timeout time return callRPC(ctx1, c.client, req) } -// Close implements Client.Close +// Close implements Client.Close. func (c *GRPCClient) Close() error { defer func() { atomic.CompareAndSwapInt32(&c.closed, 0, 1) @@ -91,8 +91,7 @@ func (c *GRPCClient) Close() error { if c.conn == nil { return nil } - err := c.conn.Close() - if err != nil { + if err := c.conn.Close(); err != nil { return terror.ErrMasterGRPCClientClose.Delegate(err) } return nil diff --git a/dm/master/workerrpc/workerrpc_test.go b/dm/master/workerrpc/workerrpc_test.go index f664a5257c..e55c1b6a08 100644 --- a/dm/master/workerrpc/workerrpc_test.go +++ b/dm/master/workerrpc/workerrpc_test.go @@ -31,8 +31,7 @@ import ( var _ = Suite(&testWorkerRPCSuite{}) -type testWorkerRPCSuite struct { -} +type testWorkerRPCSuite struct{} func TestWorkerRPC(t *testing.T) { TestingT(t) diff --git a/dm/pb/hide_password.go b/dm/pb/hide_password.go index e0ac1da586..6e10847a27 100644 --- a/dm/pb/hide_password.go +++ b/dm/pb/hide_password.go @@ -4,20 +4,18 @@ import ( "go.uber.org/zap/zapcore" ) -var ( - // HidePwdFunc should be overwrite by utils.HidePassword, this variable is for avoiding cycle import - HidePwdFunc = func(s string) string { - return s - } -) +// HidePwdFunc should be overwrite by utils.HidePassword, this variable is for avoiding cycle import. +var HidePwdFunc = func(s string) string { + return s +} -// MarshalLogObject implements zapcore.ObjectMarshaler +// MarshalLogObject implements zapcore.ObjectMarshaler. func (m *StartTaskRequest) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("HidePasswordObject", HidePwdFunc(m.String())) return nil } -// MarshalLogObject implements zapcore.ObjectMarshaler +// MarshalLogObject implements zapcore.ObjectMarshaler. func (m *OperateSourceRequest) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("HidePasswordObject", HidePwdFunc(m.String())) return nil diff --git a/dm/portal/api.go b/dm/portal/api.go index 9a9373bfba..365498310b 100644 --- a/dm/portal/api.go +++ b/dm/portal/api.go @@ -15,7 +15,7 @@ import ( "strings" "time" - // for database + // for database. _ "github.com/go-sql-driver/mysql" "github.com/pingcap/errors" "github.com/pingcap/tidb-tools/pkg/dbutil" @@ -39,7 +39,7 @@ const ( failed = "failed" ) -// Handler used for deal with http request +// Handler used for deal with http request. type Handler struct { r *render.Render @@ -50,7 +50,7 @@ type Handler struct { timeout int } -// NewHandler returns a new Handler +// NewHandler returns a new Handler. func NewHandler(path string, timeout int) *Handler { rd := render.New(render.Options{ IndentJSON: true, @@ -63,42 +63,42 @@ func NewHandler(path string, timeout int) *Handler { } } -// CommonResult is the common result +// CommonResult is the common result. type CommonResult struct { Result string `json:"result"` Error string `json:"error"` } -// CheckResult is the result of Check +// CheckResult is the result of Check. type CheckResult struct { CommonResult } -// SchemaInfoResult is the result of GetSchemaInfo +// SchemaInfoResult is the result of GetSchemaInfo. type SchemaInfoResult struct { CommonResult Tables []TablesInSchema `json:"tables"` } -// TablesInSchema saves all the tables in one schema +// TablesInSchema saves all the tables in one schema. type TablesInSchema struct { Schema string `json:"schema"` Tables []string `json:"tables"` } -// GenerateConfigResult is the result of GenerateConfig +// GenerateConfigResult is the result of GenerateConfig. type GenerateConfigResult struct { CommonResult Filepath string `json:"filepath"` } -// AnalyzeResult is the result of AnalyzeConfig +// AnalyzeResult is the result of AnalyzeConfig. type AnalyzeResult struct { CommonResult Config DMTaskConfig `json:"config"` } -// Check checks database can be connected +// Check checks database can be connected. func (p *Handler) Check(w http.ResponseWriter, req *http.Request) { log.L().Info("receive Check request") @@ -124,7 +124,7 @@ func (p *Handler) Check(w http.ResponseWriter, req *http.Request) { }) } -// GetSchemaInfo gets all schemas and tables information from a database +// GetSchemaInfo gets all schemas and tables information from a database. func (p *Handler) GetSchemaInfo(w http.ResponseWriter, req *http.Request) { log.L().Info("receive GetSchemaInfo request") @@ -185,7 +185,7 @@ func (p *Handler) GetSchemaInfo(w http.ResponseWriter, req *http.Request) { }) } -// GenerateConfig generates config file used for dm +// GenerateConfig generates config file used for dm. func (p *Handler) GenerateConfig(w http.ResponseWriter, req *http.Request) { log.L().Info("receive GenerateConfig request") @@ -277,7 +277,7 @@ func (p *Handler) GenerateConfig(w http.ResponseWriter, req *http.Request) { }) } -// AnalyzeConfig analyzes dm task config from front-end +// AnalyzeConfig analyzes dm task config from front-end. func (p *Handler) AnalyzeConfig(w http.ResponseWriter, req *http.Request) { log.L().Info("receive AnalyzeConfig request") @@ -355,7 +355,7 @@ func (p *Handler) AnalyzeConfig(w http.ResponseWriter, req *http.Request) { }) } -// Download returns dm task config data for generate config file +// Download returns dm task config data for generate config file. func (p *Handler) Download(w http.ResponseWriter, req *http.Request) { log.L().Info("receive Download request") @@ -402,8 +402,7 @@ func (p *Handler) Download(w http.ResponseWriter, req *http.Request) { // fileValid judge the download file path is valid or not. func (p *Handler) fileValid(filepath string) bool { - dir := path.Dir(filepath) - if dir != p.path { + if dir := path.Dir(filepath); dir != p.path { return false } @@ -531,7 +530,7 @@ func adjustConfig(cfg *DMTaskConfig) error { return nil } -// rule name looks like "instance1.route_rules.1" +// rule name looks like "instance1.route_rules.1". func analyzeRuleName(name string) (sourceID string, tp string, err error) { items := strings.Split(name, ".") if len(items) != 3 { @@ -576,7 +575,7 @@ func generateTaskFileName(taskName string) string { return fmt.Sprintf("%s-task.yaml", taskName) } -// openDB opens a mysql connection FD +// openDB opens a mysql connection FD. func openDB(cfg DBConfig, timeout int) (*sql.DB, error) { dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/?charset=utf8mb4&timeout=%ds", cfg.User, cfg.Password, cfg.Host, cfg.Port, timeout) diff --git a/dm/portal/config.go b/dm/portal/config.go index 91b75805b8..27b2610273 100644 --- a/dm/portal/config.go +++ b/dm/portal/config.go @@ -7,17 +7,18 @@ import ( "os" "path" - "github.com/pingcap/dm/dm/config" - "github.com/pingcap/dm/pkg/log" - "github.com/pingcap/dm/pkg/utils" "github.com/pingcap/errors" bf "github.com/pingcap/tidb-tools/pkg/binlog-filter" "github.com/pingcap/tidb-tools/pkg/filter" router "github.com/pingcap/tidb-tools/pkg/table-router" "go.uber.org/zap" + + "github.com/pingcap/dm/dm/config" + "github.com/pingcap/dm/pkg/log" + "github.com/pingcap/dm/pkg/utils" ) -// Config is the dm-portal's config +// Config is the dm-portal's config. type Config struct { *flag.FlagSet `json:"-"` @@ -47,7 +48,7 @@ func NewConfig() *Config { return cfg } -// Parse parses the cmd config +// Parse parses the cmd config. func (cfg *Config) Parse(arguments []string) { // Parse first to get config file perr := cfg.FlagSet.Parse(arguments) @@ -65,7 +66,7 @@ func (cfg *Config) Parse(arguments []string) { } } -// Valid checks whether the config is valid +// Valid checks whether the config is valid. func (cfg *Config) Valid() error { if cfg.Port < 1 || cfg.Port > 65535 { return errors.Errorf("port %d is out of range [1, 65535]", cfg.Port) @@ -93,12 +94,12 @@ func (cfg *Config) Valid() error { return nil } -// String return config's string +// String return config's string. func (cfg *Config) String() string { return fmt.Sprintf("dm-portal config: { port: %d, task-file-path: %s }", cfg.Port, cfg.TaskFilePath) } -// DMTaskConfig is the dm task's config used for dm-portal +// DMTaskConfig is the dm task's config used for dm-portal. type DMTaskConfig struct { Name string `yaml:"name" json:"name"` @@ -127,7 +128,7 @@ func (d *DMTaskConfig) String() string { return string(cfgBytes) } -// Verify does verification on DMTaskConfig +// Verify does verification on DMTaskConfig. func (d *DMTaskConfig) Verify() error { if len(d.Name) == 0 { return errors.New("task name should not be empty") @@ -150,7 +151,7 @@ func (d *DMTaskConfig) Verify() error { return nil } -// MySQLInstance represents a sync config of a MySQL instance +// MySQLInstance represents a sync config of a MySQL instance. type MySQLInstance struct { // it represents a MySQL/MariaDB instance or a replica group SourceID string `yaml:"source-id" json:"source-id"` @@ -181,7 +182,7 @@ func (m *MySQLInstance) Verify() error { return nil } -// DBConfig is the DB's config +// DBConfig is the DB's config. type DBConfig struct { Host string `yaml:"host" json:"host"` @@ -194,13 +195,13 @@ type DBConfig struct { // Meta represents binlog's meta pos // NOTE: refine to put these config structs into pkgs -// NOTE: now, syncer does not support GTID mode and which is supported by relay +// NOTE: now, syncer does not support GTID mode and which is supported by relay. type Meta struct { BinLogName string `yaml:"binlog-name" json:"binlog-name"` BinLogPos uint32 `yaml:"binlog-pos" json:"binlog-pos"` } -// Verify does verification on configs +// Verify does verification on configs. func (m *Meta) Verify() error { if m != nil && len(m.BinLogName) == 0 { return errors.New("binlog-name must specify") diff --git a/dm/unit/unit.go b/dm/unit/unit.go index a15ea031ed..fa0e765e7f 100644 --- a/dm/unit/unit.go +++ b/dm/unit/unit.go @@ -59,7 +59,7 @@ type Unit interface { } // NewProcessError creates a new ProcessError -// we can refine to add error scope field if needed +// we can refine to add error scope field if needed. func NewProcessError(err error) *pb.ProcessError { if e, ok := err.(*terror.Error); ok { return &pb.ProcessError{ @@ -84,12 +84,12 @@ func NewProcessError(err error) *pb.ProcessError { } } -// IsCtxCanceledProcessErr returns true if the err's context canceled +// IsCtxCanceledProcessErr returns true if the err's context canceled. func IsCtxCanceledProcessErr(err *pb.ProcessError) bool { return strings.Contains(err.Message, "context canceled") } -// JoinProcessErrors return the string of pb.ProcessErrors joined by ", " +// JoinProcessErrors return the string of pb.ProcessErrors joined by ", ". func JoinProcessErrors(errors []*pb.ProcessError) string { serrs := make([]string, 0, len(errors)) for _, serr := range errors { diff --git a/dm/worker/config.go b/dm/worker/config.go index b6e2fd2730..602be5d0d3 100644 --- a/dm/worker/config.go +++ b/dm/worker/config.go @@ -33,7 +33,7 @@ import ( // SampleConfigFile is sample config file of dm-worker // later we can read it from dm/worker/dm-worker.toml -// and assign it to SampleConfigFile while we build dm-worker +// and assign it to SampleConfigFile while we build dm-worker. var ( SampleConfigFile string defaultKeepAliveTTL = int64(60) // 1 minute @@ -65,7 +65,7 @@ func NewConfig() *Config { fs.StringVar(&cfg.LogLevel, "L", "info", "log level: debug, info, warn, error, fatal") fs.StringVar(&cfg.LogFile, "log-file", "", "log file path") fs.StringVar(&cfg.LogFormat, "log-format", "text", `the format of the log, "text" or "json"`) - //fs.StringVar(&cfg.LogRotate, "log-rotate", "day", "log file rotate type, hour/day") + // fs.StringVar(&cfg.LogRotate, "log-rotate", "day", "log file rotate type, hour/day") // NOTE: add `advertise-addr` for dm-master if needed. fs.StringVar(&cfg.Join, "join", "", `join to an existing cluster (usage: dm-master cluster's "${master-addr}")`) fs.StringVar(&cfg.Name, "name", "", "human-readable name for DM-worker member") @@ -106,7 +106,7 @@ type Config struct { printSampleConfig bool } -// Clone clones a config +// Clone clones a config. func (c *Config) Clone() *Config { clone := &Config{} *clone = *c @@ -121,7 +121,7 @@ func (c *Config) String() string { return string(cfg) } -// Toml returns TOML format representation of config +// Toml returns TOML format representation of config. func (c *Config) Toml() (string, error) { var b bytes.Buffer diff --git a/dm/worker/config_test.go b/dm/worker/config_test.go index 2efb8cc5c0..e853d9a4ff 100644 --- a/dm/worker/config_test.go +++ b/dm/worker/config_test.go @@ -24,8 +24,7 @@ var ( _ = check.Suite(&testConfigSuite{}) ) -type testConfigSuite struct { -} +type testConfigSuite struct{} func (t *testConfigSuite) TestAdjustAddr(c *check.C) { cfg := NewConfig() diff --git a/dm/worker/hub.go b/dm/worker/hub.go index b2c39e1635..b3b32726d5 100644 --- a/dm/worker/hub.go +++ b/dm/worker/hub.go @@ -13,23 +13,21 @@ package worker -var ( - conditionHub *ConditionHub -) +var conditionHub *ConditionHub -// ConditionHub holds a DM-worker and it is used for wait condition detection +// ConditionHub holds a DM-worker and it is used for wait condition detection. type ConditionHub struct { w *Worker } -// InitConditionHub inits the singleton instance of ConditionHub +// InitConditionHub inits the singleton instance of ConditionHub. func InitConditionHub(w *Worker) { conditionHub = &ConditionHub{ w: w, } } -// GetConditionHub returns singleton instance of ConditionHub +// GetConditionHub returns singleton instance of ConditionHub. func GetConditionHub() *ConditionHub { return conditionHub } diff --git a/dm/worker/join.go b/dm/worker/join.go index b0cd59f9ea..a610c2e33f 100644 --- a/dm/worker/join.go +++ b/dm/worker/join.go @@ -119,7 +119,7 @@ func (s *Server) KeepAlive() { } } -// UpdateKeepAliveTTL updates keepalive key with new lease TTL in place, to avoid watcher observe a DELETE event +// UpdateKeepAliveTTL updates keepalive key with new lease TTL in place, to avoid watcher observe a DELETE event. func (s *Server) UpdateKeepAliveTTL(newTTL int64) { ha.KeepAliveUpdateCh <- newTTL log.L().Debug("received update keepalive TTL request, should be updated soon", zap.Int64("new ttl", newTTL)) diff --git a/dm/worker/metrics.go b/dm/worker/metrics.go index a2c816a402..70a92dfa54 100644 --- a/dm/worker/metrics.go +++ b/dm/worker/metrics.go @@ -49,7 +49,7 @@ var ( Help: "state of task, 0 - invalidStage, 1 - New, 2 - Running, 3 - Paused, 4 - Stopped, 5 - Finished", }, []string{"task", "source_id"}) - // opErrCounter cleans on worker close, which is the same time dm-worker exits, so no explicit clean + // opErrCounter cleans on worker close, which is the same time dm-worker exits, so no explicit clean. opErrCounter = metricsproxy.NewCounterVec( prometheus.CounterOpts{ Namespace: "dm", @@ -67,8 +67,7 @@ var ( }) ) -type statusHandler struct { -} +type statusHandler struct{} func (h *statusHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") @@ -101,7 +100,7 @@ func (s *Server) runBackgroundJob(ctx context.Context) { } } -// RegistryMetrics registries metrics for worker +// RegistryMetrics registries metrics for worker. func RegistryMetrics() { registry := prometheus.NewRegistry() registry.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) @@ -119,7 +118,7 @@ func RegistryMetrics() { prometheus.DefaultGatherer = registry } -// InitStatus initializes the HTTP status server +// InitStatus initializes the HTTP status server. func InitStatus(lis net.Listener) { mux := http.NewServeMux() mux.Handle("/status", &statusHandler{}) diff --git a/dm/worker/relay.go b/dm/worker/relay.go index 44b593909e..da2ffdf587 100644 --- a/dm/worker/relay.go +++ b/dm/worker/relay.go @@ -30,7 +30,7 @@ import ( "github.com/pingcap/dm/relay/purger" ) -// RelayHolder for relay unit +// RelayHolder for relay unit. type RelayHolder interface { // Init initializes the holder Init(ctx context.Context, interceptors []purger.PurgeInterceptor) (purger.Purger, error) @@ -53,10 +53,10 @@ type RelayHolder interface { } // NewRelayHolder is relay holder initializer -// it can be used for testing +// it can be used for testing. var NewRelayHolder = NewRealRelayHolder -// realRelayHolder used to hold the relay unit +// realRelayHolder used to hold the relay unit. type realRelayHolder struct { sync.RWMutex wg sync.WaitGroup @@ -74,7 +74,7 @@ type realRelayHolder struct { result *pb.ProcessResult // the process result, nil when is processing } -// NewRealRelayHolder creates a new RelayHolder +// NewRealRelayHolder creates a new RelayHolder. func NewRealRelayHolder(sourceCfg *config.SourceConfig) RelayHolder { cfg := relay.FromSourceCfg(sourceCfg) @@ -88,7 +88,7 @@ func NewRealRelayHolder(sourceCfg *config.SourceConfig) RelayHolder { return h } -// Init initializes the holder +// Init initializes the holder. func (h *realRelayHolder) Init(ctx context.Context, interceptors []purger.PurgeInterceptor) (purger.Purger, error) { h.closed.Set(false) @@ -105,7 +105,7 @@ func (h *realRelayHolder) Init(ctx context.Context, interceptors []purger.PurgeI return purger.NewPurger(h.cfg.Purge, h.cfg.RelayDir, operators, interceptors), nil } -// Start starts run the relay +// Start starts run the relay. func (h *realRelayHolder) Start() { h.wg.Add(1) go func() { @@ -114,7 +114,7 @@ func (h *realRelayHolder) Start() { }() } -// Close closes the holder +// Close closes the holder. func (h *realRelayHolder) Close() { if !h.closed.CompareAndSwap(false, true) { return @@ -147,7 +147,7 @@ func (h *realRelayHolder) run() { h.setStageIfNot(pb.Stage_Stopped, pb.Stage_Paused) } -// Status returns relay unit's status +// Status returns relay unit's status. func (h *realRelayHolder) Status(ctx context.Context) *pb.RelayStatus { if h.closed.Get() || h.relay.IsClosed() { return &pb.RelayStatus{ @@ -162,7 +162,7 @@ func (h *realRelayHolder) Status(ctx context.Context) *pb.RelayStatus { return s } -// Error returns relay unit's status +// Error returns relay unit's status. func (h *realRelayHolder) Error() *pb.RelayError { if h.closed.Get() || h.relay.IsClosed() { return &pb.RelayError{ @@ -174,7 +174,7 @@ func (h *realRelayHolder) Error() *pb.RelayError { return s } -// Operate operates relay unit +// Operate operates relay unit. func (h *realRelayHolder) Operate(ctx context.Context, op pb.RelayOp) error { switch op { case pb.RelayOp_PauseRelay: @@ -235,7 +235,7 @@ func (h *realRelayHolder) stopRelay(_ context.Context, op pb.RelayOp) error { return nil } -// Stage returns the stage of the relay +// Stage returns the stage of the relay. func (h *realRelayHolder) Stage() pb.Stage { h.RLock() defer h.RUnlock() @@ -248,7 +248,7 @@ func (h *realRelayHolder) setStage(stage pb.Stage) { h.stage = stage } -// setStageIfNot sets stage to newStage if its current value is not oldStage, similar to CAS +// setStageIfNot sets stage to newStage if its current value is not oldStage, similar to CAS. func (h *realRelayHolder) setStageIfNot(oldStage, newStage pb.Stage) bool { h.Lock() defer h.Unlock() @@ -280,13 +280,11 @@ func (h *realRelayHolder) Result() *pb.ProcessResult { return h.result } -// Update update relay config online +// Update update relay config online. func (h *realRelayHolder) Update(ctx context.Context, sourceCfg *config.SourceConfig) error { relayCfg := relay.FromSourceCfg(sourceCfg) - stage := h.Stage() - - if stage == pb.Stage_Paused { + if stage := h.Stage(); stage == pb.Stage_Paused { err := h.relay.Reload(relayCfg) if err != nil { return err @@ -311,7 +309,7 @@ func (h *realRelayHolder) Update(ctx context.Context, sourceCfg *config.SourceCo return nil } -// EarliestActiveRelayLog implements RelayOperator.EarliestActiveRelayLog +// EarliestActiveRelayLog implements RelayOperator.EarliestActiveRelayLog. func (h *realRelayHolder) EarliestActiveRelayLog() *streamer.RelayLogInfo { return h.relay.ActiveRelayLog() } @@ -327,7 +325,7 @@ type dummyRelayHolder struct { cfg *config.SourceConfig } -// NewDummyRelayHolder creates a new RelayHolder +// NewDummyRelayHolder creates a new RelayHolder. func NewDummyRelayHolder(cfg *config.SourceConfig) RelayHolder { return &dummyRelayHolder{ cfg: cfg, @@ -335,7 +333,7 @@ func NewDummyRelayHolder(cfg *config.SourceConfig) RelayHolder { } } -// NewDummyRelayHolderWithRelayBinlog creates a new RelayHolder with relayBinlog in relayStatus +// NewDummyRelayHolderWithRelayBinlog creates a new RelayHolder with relayBinlog in relayStatus. func NewDummyRelayHolderWithRelayBinlog(cfg *config.SourceConfig, relayBinlog string) RelayHolder { return &dummyRelayHolder{ cfg: cfg, @@ -343,7 +341,7 @@ func NewDummyRelayHolderWithRelayBinlog(cfg *config.SourceConfig, relayBinlog st } } -// NewDummyRelayHolderWithInitError creates a new RelayHolder with init error +// NewDummyRelayHolderWithInitError creates a new RelayHolder with init error. func NewDummyRelayHolderWithInitError(cfg *config.SourceConfig) RelayHolder { return &dummyRelayHolder{ initError: errors.New("init error"), @@ -351,7 +349,7 @@ func NewDummyRelayHolderWithInitError(cfg *config.SourceConfig) RelayHolder { } } -// Init implements interface of RelayHolder +// Init implements interface of RelayHolder. func (d *dummyRelayHolder) Init(ctx context.Context, interceptors []purger.PurgeInterceptor) (purger.Purger, error) { // initial relay purger operators := []purger.RelayOperator{ @@ -361,21 +359,21 @@ func (d *dummyRelayHolder) Init(ctx context.Context, interceptors []purger.Purge return purger.NewDummyPurger(d.cfg.Purge, d.cfg.RelayDir, operators, interceptors), d.initError } -// Start implements interface of RelayHolder +// Start implements interface of RelayHolder. func (d *dummyRelayHolder) Start() { d.Lock() defer d.Unlock() d.stage = pb.Stage_Running } -// Close implements interface of RelayHolder +// Close implements interface of RelayHolder. func (d *dummyRelayHolder) Close() { d.Lock() defer d.Unlock() d.stage = pb.Stage_Stopped } -// Status implements interface of RelayHolder +// Status implements interface of RelayHolder. func (d *dummyRelayHolder) Status(ctx context.Context) *pb.RelayStatus { d.Lock() defer d.Unlock() @@ -385,12 +383,12 @@ func (d *dummyRelayHolder) Status(ctx context.Context) *pb.RelayStatus { } } -// Error implements interface of RelayHolder +// Error implements interface of RelayHolder. func (d *dummyRelayHolder) Error() *pb.RelayError { return nil } -// Operate implements interface of RelayHolder +// Operate implements interface of RelayHolder. func (d *dummyRelayHolder) Operate(ctx context.Context, op pb.RelayOp) error { d.Lock() defer d.Unlock() @@ -414,12 +412,12 @@ func (d *dummyRelayHolder) Operate(ctx context.Context, op pb.RelayOp) error { return nil } -// Result implements interface of RelayHolder +// Result implements interface of RelayHolder. func (d *dummyRelayHolder) Result() *pb.ProcessResult { return nil } -// Update implements interface of RelayHolder +// Update implements interface of RelayHolder. func (d *dummyRelayHolder) Update(ctx context.Context, cfg *config.SourceConfig) error { return nil } diff --git a/dm/worker/relay_test.go b/dm/worker/relay_test.go index 9535414389..ebc915043d 100644 --- a/dm/worker/relay_test.go +++ b/dm/worker/relay_test.go @@ -37,7 +37,7 @@ var _ = Suite(&testRelay{}) /*********** dummy relay log process unit, used only for testing *************/ -// DummyRelay is a dummy relay +// DummyRelay is a dummy relay. type DummyRelay struct { initErr error @@ -51,80 +51,80 @@ func NewDummyRelay(cfg *relay.Config) relay.Process { return &DummyRelay{} } -// Init implements Process interface +// Init implements Process interface. func (d *DummyRelay) Init(ctx context.Context) error { return d.initErr } -// InjectInitError injects init error +// InjectInitError injects init error. func (d *DummyRelay) InjectInitError(err error) { d.initErr = err } -// Process implements Process interface +// Process implements Process interface. func (d *DummyRelay) Process(ctx context.Context, pr chan pb.ProcessResult) { <-ctx.Done() pr <- d.processResult } -// InjectProcessResult injects process result +// InjectProcessResult injects process result. func (d *DummyRelay) InjectProcessResult(result pb.ProcessResult) { d.processResult = result } -// ActiveRelayLog implements Process interface +// ActiveRelayLog implements Process interface. func (d *DummyRelay) ActiveRelayLog() *pkgstreamer.RelayLogInfo { return nil } -// Reload implements Process interface +// Reload implements Process interface. func (d *DummyRelay) Reload(newCfg *relay.Config) error { return d.reloadErr } -// InjectReloadError injects reload error +// InjectReloadError injects reload error. func (d *DummyRelay) InjectReloadError(err error) { d.reloadErr = err } -// Update implements Process interface +// Update implements Process interface. func (d *DummyRelay) Update(cfg *config.SubTaskConfig) error { return nil } -// Resume implements Process interface +// Resume implements Process interface. func (d *DummyRelay) Resume(ctx context.Context, pr chan pb.ProcessResult) {} -// Pause implements Process interface +// Pause implements Process interface. func (d *DummyRelay) Pause() {} -// Error implements Process interface +// Error implements Process interface. func (d *DummyRelay) Error() interface{} { return d.errorInfo } -// Status implements Process interface +// Status implements Process interface. func (d *DummyRelay) Status(ctx context.Context) interface{} { return &pb.RelayStatus{ Stage: pb.Stage_New, } } -// Close implements Process interface +// Close implements Process interface. func (d *DummyRelay) Close() {} -// IsClosed implements Process interface +// IsClosed implements Process interface. func (d *DummyRelay) IsClosed() bool { return false } -// SaveMeta implements Process interface +// SaveMeta implements Process interface. func (d *DummyRelay) SaveMeta(pos mysql.Position, gset gtid.Set) error { return nil } -// ResetMeta implements Process interface +// ResetMeta implements Process interface. func (d *DummyRelay) ResetMeta() {} -// PurgeRelayDir implements Process interface +// PurgeRelayDir implements Process interface. func (d *DummyRelay) PurgeRelayDir() error { return nil } @@ -180,7 +180,7 @@ func (t *testRelay) testStart(c *C, holder *realRelayHolder) { c.Assert(holder.Result(), IsNil) holder.Start() - c.Assert(waitRelayStage(holder, pb.Stage_Running, 10), IsTrue) + c.Assert(waitRelayStage(holder, pb.Stage_Running, 5), IsTrue) c.Assert(holder.Result(), IsNil) c.Assert(holder.closed.Get(), IsFalse) diff --git a/dm/worker/server.go b/dm/worker/server.go index 4505b99e21..8aefd2c536 100644 --- a/dm/worker/server.go +++ b/dm/worker/server.go @@ -56,7 +56,7 @@ var ( // Server accepts RPC requests // dispatches requests to worker -// sends responses to RPC client +// sends responses to RPC client. type Server struct { sync.Mutex wg sync.WaitGroup @@ -79,7 +79,7 @@ type Server struct { sourceStatus pb.SourceStatus } -// NewServer creates a new Server +// NewServer creates a new Server. func NewServer(cfg *Config) *Server { s := Server{ cfg: cfg, @@ -88,7 +88,7 @@ func NewServer(cfg *Config) *Server { return &s } -// Start starts to serving +// Start starts to serving. func (s *Server) Start() error { log.L().Info("starting dm-worker server") RegistryMetrics() @@ -209,7 +209,6 @@ func (s *Server) Start() error { } case <-grpcExitCh: } - }(s.ctx) httpExitCh := make(chan struct{}, 1) @@ -489,13 +488,13 @@ func (s *Server) doClose() { s.closed.Set(true) } -// Close close the RPC server, this function can be called multiple times +// Close close the RPC server, this function can be called multiple times. func (s *Server) Close() { s.stopKeepAlive() s.doClose() } -// if needLock is false, we should make sure Server has been locked in caller +// if needLock is false, we should make sure Server has been locked in caller. func (s *Server) getWorker(needLock bool) *Worker { if needLock { s.Lock() @@ -504,7 +503,7 @@ func (s *Server) getWorker(needLock bool) *Worker { return s.worker } -// if needLock is false, we should make sure Server has been locked in caller +// if needLock is false, we should make sure Server has been locked in caller. func (s *Server) setWorker(worker *Worker, needLock bool) { if needLock { s.Lock() @@ -513,6 +512,7 @@ func (s *Server) setWorker(worker *Worker, needLock bool) { s.worker = worker } +// nolint:unparam func (s *Server) getSourceStatus(needLock bool) pb.SourceStatus { if needLock { s.Lock() @@ -521,7 +521,7 @@ func (s *Server) getSourceStatus(needLock bool) pb.SourceStatus { return s.sourceStatus } -// TODO: move some call to setWorker/getOrStartWorker +// TODO: move some call to setWorker/getOrStartWorker. func (s *Server) setSourceStatus(source string, err error, needLock bool) { if needLock { s.Lock() @@ -545,7 +545,7 @@ func (s *Server) setSourceStatus(source string, err error, needLock bool) { } // if sourceID is set to "", worker will be closed directly -// if sourceID is not "", we will check sourceID with w.cfg.SourceID +// if sourceID is not "", we will check sourceID with w.cfg.SourceID. func (s *Server) stopWorker(sourceID string, needLock bool) error { if needLock { s.Lock() @@ -746,7 +746,7 @@ func (s *Server) disableRelay(source string) error { return err } -// QueryStatus implements WorkerServer.QueryStatus +// QueryStatus implements WorkerServer.QueryStatus. func (s *Server) QueryStatus(ctx context.Context, req *pb.QueryStatusRequest) (*pb.QueryStatusResponse, error) { log.L().Info("", zap.String("request", "QueryStatus"), zap.Stringer("payload", req)) @@ -774,7 +774,7 @@ func (s *Server) QueryStatus(ctx context.Context, req *pb.QueryStatusRequest) (* return resp, nil } -// PurgeRelay implements WorkerServer.PurgeRelay +// PurgeRelay implements WorkerServer.PurgeRelay. func (s *Server) PurgeRelay(ctx context.Context, req *pb.PurgeRelayRequest) (*pb.CommonWorkerResponse, error) { log.L().Info("", zap.String("request", "PurgeRelay"), zap.Stringer("payload", req)) w := s.getWorker(true) @@ -860,7 +860,7 @@ func makeCommonWorkerResponse(reqErr error) *pb.CommonWorkerResponse { } // all subTask in subTaskCfgs should have same source -// this function return the min location in all subtasks, used for relay's location +// this function return the min location in all subtasks, used for relay's location. func getMinLocInAllSubTasks(ctx context.Context, subTaskCfgs map[string]config.SubTaskConfig) (minLoc *binlog.Location, err error) { for _, subTaskCfg := range subTaskCfgs { loc, err := getMinLocForSubTaskFunc(ctx, subTaskCfg) @@ -874,10 +874,8 @@ func getMinLocInAllSubTasks(ctx context.Context, subTaskCfgs map[string]config.S if minLoc == nil { minLoc = loc - } else { - if binlog.CompareLocation(*minLoc, *loc, subTaskCfg.EnableGTID) >= 1 { - minLoc = loc - } + } else if binlog.CompareLocation(*minLoc, *loc, subTaskCfg.EnableGTID) >= 1 { + minLoc = loc } } @@ -951,7 +949,6 @@ func unifyMasterBinlogPos(resp *pb.QueryStatusResponse, enableGTID bool) { // re-check relay if resp.SourceStatus.RelayStatus != nil && resp.SourceStatus.RelayStatus.Stage != pb.Stage_Stopped && latestMasterBinlog.Compare(*relayMasterBinlog) != 0 { - resp.SourceStatus.RelayStatus.MasterBinlog = latestMasterBinlog.String() // if enableGTID, modify output binlog position doesn't affect RelayCatchUpMaster, skip check @@ -982,7 +979,7 @@ func unifyMasterBinlogPos(resp *pb.QueryStatusResponse, enableGTID bool) { } } -// HandleError handle error +// HandleError handle error. func (s *Server) HandleError(ctx context.Context, req *pb.HandleWorkerErrorRequest) (*pb.CommonWorkerResponse, error) { log.L().Info("", zap.String("request", "HandleError"), zap.Stringer("payload", req)) @@ -992,8 +989,7 @@ func (s *Server) HandleError(ctx context.Context, req *pb.HandleWorkerErrorReque return makeCommonWorkerResponse(terror.ErrWorkerNoStart.Generate()), nil } - err := w.HandleError(ctx, req) - if err != nil { + if err := w.HandleError(ctx, req); err != nil { return makeCommonWorkerResponse(err), nil } return &pb.CommonWorkerResponse{ @@ -1002,7 +998,7 @@ func (s *Server) HandleError(ctx context.Context, req *pb.HandleWorkerErrorReque }, nil } -// GetWorkerCfg get worker config +// GetWorkerCfg get worker config. func (s *Server) GetWorkerCfg(ctx context.Context, req *pb.GetWorkerCfgRequest) (*pb.GetWorkerCfgResponse, error) { log.L().Info("", zap.String("request", "GetWorkerCfg"), zap.Stringer("payload", req)) var err error diff --git a/dm/worker/server_test.go b/dm/worker/server_test.go index 9edd585161..773f7fb05c 100644 --- a/dm/worker/server_test.go +++ b/dm/worker/server_test.go @@ -440,6 +440,7 @@ func (t *testServer) TestWatchSourceBoundEtcdCompact(c *C) { } func (t *testServer) testHTTPInterface(c *C, uri string) { + // nolint:noctx resp, err := http.Get("http://127.0.0.1:8262/" + uri) c.Assert(err, IsNil) defer resp.Body.Close() @@ -498,8 +499,8 @@ func (t *testServer) testOperateWorker(c *C, s *Server, dir string, start bool) } } -func (t *testServer) testRetryConnectMaster(c *C, s *Server, ETCD *embed.Etcd, dir string, hostName string) *embed.Etcd { - ETCD.Close() +func (t *testServer) testRetryConnectMaster(c *C, s *Server, etcd *embed.Etcd, dir string, hostName string) *embed.Etcd { + etcd.Close() time.Sleep(6 * time.Second) // When worker server fail to keepalive with etcd, server should close its worker c.Assert(s.getWorker(true), IsNil) @@ -544,14 +545,13 @@ func (t *testServer) testSubTaskRecover(c *C, s *Server, dir string) { c.Assert(status.SubTaskStatus[0].Stage, Equals, pb.Stage_Running) } -func (t *testServer) testStopWorkerWhenLostConnect(c *C, s *Server, ETCD *embed.Etcd) { - ETCD.Close() +func (t *testServer) testStopWorkerWhenLostConnect(c *C, s *Server, etcd *embed.Etcd) { + etcd.Close() time.Sleep(retryConnectSleepTime + time.Duration(defaultKeepAliveTTL+3)*time.Second) c.Assert(s.getWorker(true), IsNil) } func (t *testServer) TestGetMinLocInAllSubTasks(c *C) { - subTaskCfg := map[string]config.SubTaskConfig{ "test2": {Name: "test2"}, "test3": {Name: "test3"}, diff --git a/dm/worker/status.go b/dm/worker/status.go index 662c9c9f0e..59cbef85d2 100644 --- a/dm/worker/status.go +++ b/dm/worker/status.go @@ -25,7 +25,7 @@ import ( "github.com/pingcap/dm/dm/pb" ) -// Status returns the status of the current sub task +// Status returns the status of the current sub task. func (st *SubTask) Status(ctx context.Context) interface{} { if cu := st.CurrUnit(); cu != nil { return cu.Status(ctx) @@ -33,7 +33,7 @@ func (st *SubTask) Status(ctx context.Context) interface{} { return nil } -// StatusJSON returns the status of the current sub task as json string +// StatusJSON returns the status of the current sub task as json string. func (st *SubTask) StatusJSON(ctx context.Context) string { status := st.Status(ctx) sj, err := json.Marshal(status) @@ -45,9 +45,8 @@ func (st *SubTask) StatusJSON(ctx context.Context) string { } // Status returns the status of the worker (and sub tasks) -// if stName is empty, all sub task's status will be returned +// if stName is empty, all sub task's status will be returned. func (w *Worker) Status(ctx context.Context, stName string) []*pb.SubTaskStatus { - sts := w.subTaskHolder.getAllSubTasks() if len(sts) == 0 { @@ -76,7 +75,7 @@ func (w *Worker) Status(ctx context.Context, stName string) []*pb.SubTaskStatus Status: &pb.SubTaskStatus_Msg{Msg: fmt.Sprintf("no sub task with name %s has started", name)}, } } else { - var lockID = "" + lockID := "" op := st.ShardDDLOperation() if op != nil { lockID = op.ID @@ -112,7 +111,7 @@ func (w *Worker) Status(ctx context.Context, stName string) []*pb.SubTaskStatus return status } -// StatusJSON returns the status of the worker as json string +// StatusJSON returns the status of the worker as json string. func (w *Worker) StatusJSON(ctx context.Context, stName string) string { sl := &pb.SubTaskStatusList{Status: w.Status(ctx, stName)} mar := jsonpb.Marshaler{EmitDefaults: true, Indent: " "} diff --git a/dm/worker/subtask.go b/dm/worker/subtask.go index 233c10ccfb..3a4ab0a499 100644 --- a/dm/worker/subtask.go +++ b/dm/worker/subtask.go @@ -44,10 +44,10 @@ const ( ) // createRealUnits is subtask units initializer -// it can be used for testing +// it can be used for testing. var createUnits = createRealUnits -// createRealUnits creates process units base on task mode +// createRealUnits creates process units base on task mode. func createRealUnits(cfg *config.SubTaskConfig, etcdClient *clientv3.Client) []unit.Unit { failpoint.Inject("mockCreateUnitsDumpOnly", func(_ failpoint.Value) { log.L().Info("create mock worker units with dump unit only", zap.String("failpoint", "mockCreateUnitsDumpOnly")) @@ -72,7 +72,7 @@ func createRealUnits(cfg *config.SubTaskConfig, etcdClient *clientv3.Client) []u return us } -// SubTask represents a sub task of data migration +// SubTask represents a sub task of data migration. type SubTask struct { cfg *config.SubTaskConfig @@ -81,7 +81,6 @@ type SubTask struct { l log.Logger sync.RWMutex - wg sync.WaitGroup // ctx is used for the whole subtask. It will be created only when we new a subtask. ctx context.Context cancel context.CancelFunc @@ -92,6 +91,7 @@ type SubTask struct { units []unit.Unit // units do job one by one currUnit unit.Unit prevUnit unit.Unit + wg sync.WaitGroup stage pb.Stage // stage of current sub task result *pb.ProcessResult // the process result, nil when is processing @@ -100,15 +100,15 @@ type SubTask struct { } // NewSubTask is subtask initializer -// it can be used for testing +// it can be used for testing. var NewSubTask = NewRealSubTask -// NewRealSubTask creates a new SubTask +// NewRealSubTask creates a new SubTask. func NewRealSubTask(cfg *config.SubTaskConfig, etcdClient *clientv3.Client) *SubTask { return NewSubTaskWithStage(cfg, pb.Stage_New, etcdClient) } -// NewSubTaskWithStage creates a new SubTask with stage +// NewSubTaskWithStage creates a new SubTask with stage. func NewSubTaskWithStage(cfg *config.SubTaskConfig, stage pb.Stage, etcdClient *clientv3.Client) *SubTask { ctx, cancel := context.WithCancel(context.Background()) st := SubTask{ @@ -123,7 +123,7 @@ func NewSubTaskWithStage(cfg *config.SubTaskConfig, stage pb.Stage, etcdClient * return &st } -// Init initializes the sub task processing units +// Init initializes the sub task processing units. func (st *SubTask) Init() error { st.units = createUnits(st.cfg, st.etcdClient) if len(st.units) < 1 { @@ -160,7 +160,7 @@ func (st *SubTask) Init() error { } // if the sub task ran before, some units may be skipped - var skipIdx = 0 + skipIdx := 0 for i := len(st.units) - 1; i > 0; i-- { u := st.units[i] ctx, cancel := context.WithTimeout(context.Background(), unit.DefaultInitTimeout) @@ -183,15 +183,14 @@ func (st *SubTask) Init() error { return nil } -// Run runs the sub task +// Run runs the sub task. func (st *SubTask) Run(expectStage pb.Stage) { if st.Stage() == pb.Stage_Finished || st.Stage() == pb.Stage_Running { st.l.Warn("prepare to run a subtask with invalid stage", zap.Stringer("current stage", st.Stage())) return } - err := st.Init() - if err != nil { + if err := st.Init(); err != nil { st.l.Error("fail to initial subtask", log.ShortError(err)) st.fail(err) return @@ -246,7 +245,7 @@ func (st *SubTask) callCurrCancel() { } // fetchResult fetches units process result -// when dm-unit report an error, we need to re-Process the sub task +// when dm-unit report an error, we need to re-Process the sub task. func (st *SubTask) fetchResult(pr chan pb.ProcessResult) { defer st.wg.Done() @@ -314,31 +313,30 @@ func (st *SubTask) fetchResult(pr chan pb.ProcessResult) { } } -// setCurrUnit set current dm unit to ut and returns previous unit -func (st *SubTask) setCurrUnit(ut unit.Unit) unit.Unit { +// setCurrUnit set current dm unit to ut. +func (st *SubTask) setCurrUnit(ut unit.Unit) { st.Lock() defer st.Unlock() pu := st.currUnit st.currUnit = ut st.prevUnit = pu - return pu } -// CurrUnit returns current dm unit +// CurrUnit returns current dm unit. func (st *SubTask) CurrUnit() unit.Unit { st.RLock() defer st.RUnlock() return st.currUnit } -// PrevUnit returns dm previous unit +// PrevUnit returns dm previous unit. func (st *SubTask) PrevUnit() unit.Unit { st.RLock() defer st.RUnlock() return st.prevUnit } -// closeUnits closes all un-closed units (current unit and all the subsequent units) +// closeUnits closes all un-closed units (current unit and all the subsequent units). func (st *SubTask) closeUnits() { st.RLock() defer st.RUnlock() @@ -364,7 +362,7 @@ func (st *SubTask) closeUnits() { } // getNextUnit gets the next process unit from st.units -// if no next unit, return nil +// if no next unit, return nil. func (st *SubTask) getNextUnit() unit.Unit { var ( nu unit.Unit @@ -390,7 +388,7 @@ func (st *SubTask) setStage(stage pb.Stage) { taskState.WithLabelValues(st.cfg.Name, st.cfg.SourceID).Set(float64(st.stage)) } -// stageCAS sets stage to newStage if its current value is oldStage +// stageCAS sets stage to newStage if its current value is oldStage. func (st *SubTask) stageCAS(oldStage, newStage pb.Stage) bool { st.Lock() defer st.Unlock() @@ -403,7 +401,7 @@ func (st *SubTask) stageCAS(oldStage, newStage pb.Stage) bool { return false } -// setStageIfNot sets stage to newStage if its current value is not oldStage, similar to CAS +// setStageIfNot sets stage to newStage if its current value is not oldStage, similar to CAS. func (st *SubTask) setStageIfNot(oldStage, newStage pb.Stage) bool { st.Lock() defer st.Unlock() @@ -415,7 +413,7 @@ func (st *SubTask) setStageIfNot(oldStage, newStage pb.Stage) bool { return false } -// Stage returns the stage of the sub task +// Stage returns the stage of the sub task. func (st *SubTask) Stage() pb.Stage { st.RLock() defer st.RUnlock() @@ -428,14 +426,14 @@ func (st *SubTask) setResult(result *pb.ProcessResult) { st.result = result } -// Result returns the result of the sub task +// Result returns the result of the sub task. func (st *SubTask) Result() *pb.ProcessResult { st.RLock() defer st.RUnlock() return st.result } -// Close stops the sub task +// Close stops the sub task. func (st *SubTask) Close() { st.l.Info("closing") if st.Stage() == pb.Stage_Stopped { @@ -450,7 +448,7 @@ func (st *SubTask) Close() { st.setStageIfNot(pb.Stage_Finished, pb.Stage_Stopped) } -// Pause pauses the running sub task +// Pause pauses the running sub task. func (st *SubTask) Pause() error { if !st.stageCAS(pb.Stage_Running, pb.Stage_Pausing) { return terror.ErrWorkerNotRunningStage.Generate(st.Stage().String()) @@ -468,7 +466,7 @@ func (st *SubTask) Pause() error { } // Resume resumes the paused sub task -// similar to Run +// similar to Run. func (st *SubTask) Resume() error { if !st.initialized.Get() { st.Run(pb.Stage_Running) @@ -490,6 +488,7 @@ func (st *SubTask) Resume() error { } else if ctx.Err() != nil { // ctx.Err() != nil means this context is canceled in other go routine, // that go routine will change the stage, so don't need to set stage to paused here. + // nolint:nilerr return nil } @@ -506,7 +505,7 @@ func (st *SubTask) Resume() error { return nil } -// Update update the sub task's config +// Update update the sub task's config. func (st *SubTask) Update(cfg *config.SubTaskConfig) error { if !st.stageCAS(pb.Stage_Paused, pb.Stage_Paused) { // only test for Paused return terror.ErrWorkerUpdateTaskStage.Generate(st.Stage().String()) @@ -537,7 +536,7 @@ func (st *SubTask) OperateSchema(ctx context.Context, req *pb.OperateWorkerSchem return syncUnit.OperateSchema(ctx, req) } -// UpdateFromConfig updates config for `From` +// UpdateFromConfig updates config for `From`. func (st *SubTask) UpdateFromConfig(cfg *config.SubTaskConfig) error { st.Lock() defer st.Unlock() @@ -554,7 +553,7 @@ func (st *SubTask) UpdateFromConfig(cfg *config.SubTaskConfig) error { return nil } -// CheckUnit checks whether current unit is sync unit +// CheckUnit checks whether current unit is sync unit. func (st *SubTask) CheckUnit() bool { st.Lock() defer st.Unlock() @@ -676,7 +675,7 @@ func (st *SubTask) fail(err error) { }) } -// HandleError handle error for syncer unit +// HandleError handle error for syncer unit. func (st *SubTask) HandleError(ctx context.Context, req *pb.HandleWorkerErrorRequest) error { syncUnit, ok := st.currUnit.(*syncer.Syncer) if !ok { diff --git a/dm/worker/subtask_holder.go b/dm/worker/subtask_holder.go index 7627db23af..20d3bcde41 100644 --- a/dm/worker/subtask_holder.go +++ b/dm/worker/subtask_holder.go @@ -47,7 +47,7 @@ func (h *subTaskHolder) removeSubTask(name string) { delete(h.subTasks, name) } -// resetAllSubTasks does Close, change cfg.UseRelay then Init the subtasks +// resetAllSubTasks does Close, change cfg.UseRelay then Init the subtasks. func (h *subTaskHolder) resetAllSubTasks(useRelay bool) { h.mu.Lock() defer h.mu.Unlock() diff --git a/dm/worker/subtask_test.go b/dm/worker/subtask_test.go index 2b70bafe1d..17c5cb406c 100644 --- a/dm/worker/subtask_test.go +++ b/dm/worker/subtask_test.go @@ -31,7 +31,7 @@ import ( ) const ( - // mocked loadMetaBinlog must be greater than relayHolderBinlog + // mocked loadMetaBinlog must be greater than relayHolderBinlog. loadMetaBinlog = "(mysql-bin.00001,154)" relayHolderBinlog = "(mysql-bin.00001,150)" ) @@ -76,10 +76,10 @@ type MockUnit struct { errInit error errUpdate error - isFresh bool errFresh error - typ pb.UnitType + typ pb.UnitType + isFresh bool } func NewMockUnit(typ pb.UnitType) *MockUnit { diff --git a/dm/worker/task_checker.go b/dm/worker/task_checker.go index 243b96ce5d..7237cb2130 100644 --- a/dm/worker/task_checker.go +++ b/dm/worker/task_checker.go @@ -33,17 +33,17 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -//// Backoff related constants -//var ( -// DefaultCheckInterval = 5 * time.Second -// DefaultBackoffRollback = 5 * time.Minute -// DefaultBackoffMin = 1 * time.Second -// DefaultBackoffMax = 5 * time.Minute -// DefaultBackoffJitter = true -// DefaultBackoffFactor float64 = 2 -//) - -// ResumeStrategy represents what we can do when we meet a paused task in task status checker +// Backoff related constants +// var ( +// DefaultCheckInterval = 5 * time.Second +// DefaultBackoffRollback = 5 * time.Minute +// DefaultBackoffMin = 1 * time.Second +// DefaultBackoffMax = 5 * time.Minute +// DefaultBackoffJitter = true +// DefaultBackoffFactor float64 = 2 +// ) + +// ResumeStrategy represents what we can do when we meet a paused task in task status checker. type ResumeStrategy int // resume strategies, in each round of `check`, the checker will apply one of the following strategies @@ -71,9 +71,9 @@ const ( // for this task in this check round. ResumeSkip // When checker detects a task is paused because of some un-resumable error, such as paused because of - // executing incompatible DDL to downstream, we will apply ResumeNoSense strategy + // executing incompatible DDL to downstream, we will apply ResumeNoSense strategy. ResumeNoSense - // ResumeDispatch means we will dispatch an auto resume operation in this check round for the paused task + // ResumeDispatch means we will dispatch an auto resume operation in this check round for the paused task. ResumeDispatch ) @@ -84,7 +84,7 @@ var resumeStrategy2Str = map[ResumeStrategy]string{ ResumeDispatch: "dispatch auto resume", } -// String implements fmt.Stringer interface +// String implements fmt.Stringer interface. func (bs ResumeStrategy) String() string { if s, ok := resumeStrategy2Str[bs]; ok { return s @@ -92,7 +92,7 @@ func (bs ResumeStrategy) String() string { return fmt.Sprintf("unsupported resume strategy: %d", bs) } -// TaskStatusChecker is an interface that defines how we manage task status +// TaskStatusChecker is an interface that defines how we manage task status. type TaskStatusChecker interface { // Init initializes the checker Init() error @@ -102,7 +102,7 @@ type TaskStatusChecker interface { Close() } -// NewTaskStatusChecker is a TaskStatusChecker initializer +// NewTaskStatusChecker is a TaskStatusChecker initializer. var NewTaskStatusChecker = NewRealTaskStatusChecker type backoffController struct { @@ -124,7 +124,7 @@ type backoffController struct { relayBackoff *backoff.Backoff } -// newBackoffController returns a new backoffController instance +// newBackoffController returns a new backoffController instance. func newBackoffController() *backoffController { return &backoffController{ backoffs: make(map[string]*backoff.Backoff), @@ -149,7 +149,7 @@ type realTaskStatusChecker struct { bc *backoffController } -// NewRealTaskStatusChecker creates a new realTaskStatusChecker instance +// NewRealTaskStatusChecker creates a new realTaskStatusChecker instance. func NewRealTaskStatusChecker(cfg config.CheckerConfig, w *Worker) TaskStatusChecker { tsc := &realTaskStatusChecker{ cfg: cfg, @@ -161,7 +161,7 @@ func NewRealTaskStatusChecker(cfg config.CheckerConfig, w *Worker) TaskStatusChe return tsc } -// Init implements TaskStatusChecker.Init +// Init implements TaskStatusChecker.Init. func (tsc *realTaskStatusChecker) Init() error { // just check configuration of backoff here, lazy creates backoff counter, // as we can't get task information before dm-worker starts @@ -169,7 +169,7 @@ func (tsc *realTaskStatusChecker) Init() error { return terror.WithClass(err, terror.ClassDMWorker) } -// Start implements TaskStatusChecker.Start +// Start implements TaskStatusChecker.Start. func (tsc *realTaskStatusChecker) Start() { tsc.wg.Add(1) go func() { @@ -178,7 +178,7 @@ func (tsc *realTaskStatusChecker) Start() { }() } -// Close implements TaskStatusChecker.Close +// Close implements TaskStatusChecker.Close. func (tsc *realTaskStatusChecker) Close() { if !tsc.closed.CompareAndSwap(false, true) { return @@ -219,7 +219,7 @@ func (tsc *realTaskStatusChecker) run() { } // isResumableError checks the error message and returns whether we need to -// resume the task and retry +// resume the task and retry. func isResumableError(err *pb.ProcessError) bool { if err == nil { return true @@ -263,9 +263,10 @@ func (tsc *realTaskStatusChecker) getResumeStrategy(stStatus *pb.SubTaskStatus, // TODO: use different strategies based on the error detail for _, processErr := range stStatus.Result.Errors { + pErr := processErr if !isResumableError(processErr) { failpoint.Inject("TaskCheckInterval", func(_ failpoint.Value) { - tsc.l.Info("error is not resumable", zap.Stringer("error", processErr)) + tsc.l.Info("error is not resumable", zap.Stringer("error", pErr)) }) return ResumeNoSense } diff --git a/dm/worker/task_checker_test.go b/dm/worker/task_checker_test.go index 2eafc6167d..896cb7ab1f 100644 --- a/dm/worker/task_checker_test.go +++ b/dm/worker/task_checker_test.go @@ -142,10 +142,8 @@ func (s *testTaskCheckerSuite) TestCheck(c *check.C) { IsCanceled: false, Errors: []*pb.ProcessError{unsupporteModifyColumnError}, } - latestPausedTime = rtsc.bc.latestPausedTime[taskName] rtsc.check() c.Assert(latestPausedTime.Before(rtsc.bc.latestPausedTime[taskName]), check.IsTrue) - latestPausedTime = rtsc.bc.latestPausedTime[taskName] latestBlockTime = rtsc.bc.latestBlockTime[taskName] time.Sleep(200 * time.Millisecond) rtsc.check() diff --git a/dm/worker/v1meta.go b/dm/worker/v1meta.go index 8d64335cbe..2f13761599 100644 --- a/dm/worker/v1meta.go +++ b/dm/worker/v1meta.go @@ -32,6 +32,7 @@ func (s *Server) OperateV1Meta(ctx context.Context, req *pb.OperateV1MetaRequest case pb.V1MetaOp_GetV1Meta: meta, err := v1workermeta.GetSubtasksMeta() if err != nil { + // nolint:nilerr return &pb.OperateV1MetaResponse{ Result: false, Msg: err.Error(), @@ -44,6 +45,7 @@ func (s *Server) OperateV1Meta(ctx context.Context, req *pb.OperateV1MetaRequest case pb.V1MetaOp_RemoveV1Meta: err := v1workermeta.RemoveSubtasksMeta() if err != nil { + // nolint:nilerr return &pb.OperateV1MetaResponse{ Result: false, Msg: err.Error(), diff --git a/dm/worker/worker.go b/dm/worker/worker.go index 3d2583a0d6..88e0b58075 100644 --- a/dm/worker/worker.go +++ b/dm/worker/worker.go @@ -38,7 +38,7 @@ import ( "github.com/pingcap/dm/relay/purger" ) -// Worker manages sub tasks and process units for data migration +// Worker manages sub tasks and process units for data migration. type Worker struct { // ensure no other operation can be done when closing (we can use `WatGroup`/`Context` to archive this) // TODO: check what does it guards. Now it's used to guard relayHolder and relayPurger (maybe subTaskHolder?) since @@ -79,7 +79,7 @@ type Worker struct { } // NewWorker creates a new Worker. The functionality of relay and subtask is disabled by default, need call EnableRelay -// and EnableSubtask later +// and EnableSubtask later. func NewWorker(cfg *config.SourceConfig, etcdClient *clientv3.Client, name string) (w *Worker, err error) { w = &Worker{ cfg: cfg, @@ -119,7 +119,7 @@ func NewWorker(cfg *config.SourceConfig, etcdClient *clientv3.Client, name strin return w, nil } -// Start starts working +// Start starts working. func (w *Worker) Start() { // start task status checker if w.cfg.Checker.CheckEnable { @@ -145,7 +145,7 @@ func (w *Worker) Start() { } } -// Close stops working and releases resources +// Close stops working and releases resources. func (w *Worker) Close() { if w.closed.Get() { w.l.Warn("already closed") @@ -181,7 +181,7 @@ func (w *Worker) Close() { w.l.Info("Stop worker") } -// EnableRelay enables the functionality of start/watch/handle relay +// EnableRelay enables the functionality of start/watch/handle relay. func (w *Worker) EnableRelay() (err error) { w.l.Info("enter EnableRelay") w.Lock() @@ -199,7 +199,7 @@ func (w *Worker) EnableRelay() (err error) { return err } - dctx, dcancel := context.WithTimeout(w.etcdClient.Ctx(), time.Duration(len(subTaskCfgs))*3*time.Second) + dctx, dcancel := context.WithTimeout(w.etcdClient.Ctx(), time.Duration(len(subTaskCfgs)*3)*time.Second) defer dcancel() minLoc, err1 := getMinLocInAllSubTasks(dctx, subTaskCfgs) if err1 != nil { @@ -261,7 +261,7 @@ func (w *Worker) EnableRelay() (err error) { return nil } -// DisableRelay disables the functionality of start/watch/handle relay +// DisableRelay disables the functionality of start/watch/handle relay. func (w *Worker) DisableRelay() { w.l.Info("enter DisableRelay") w.Lock() @@ -297,7 +297,7 @@ func (w *Worker) DisableRelay() { w.l.Info("relay disabled") } -// EnableHandleSubtasks enables the functionality of start/watch/handle subtasks +// EnableHandleSubtasks enables the functionality of start/watch/handle subtasks. func (w *Worker) EnableHandleSubtasks() error { w.l.Info("enter EnableHandleSubtasks") w.Lock() @@ -344,7 +344,7 @@ func (w *Worker) EnableHandleSubtasks() error { return nil } -// DisableHandleSubtasks disables the functionality of start/watch/handle subtasks +// DisableHandleSubtasks disables the functionality of start/watch/handle subtasks. func (w *Worker) DisableHandleSubtasks() { w.l.Info("enter DisableHandleSubtasks") if !w.subTaskEnabled.CompareAndSwap(true, false) { @@ -380,7 +380,7 @@ func (w *Worker) fetchSubTasksAndAdjust() (map[string]ha.Stage, map[string]confi return subTaskStages, subTaskCfgM, revSubTask, nil } -// StartSubTask creates a sub task an run it +// StartSubTask creates a sub task an run it. func (w *Worker) StartSubTask(cfg *config.SubTaskConfig, expectStage pb.Stage, needLock bool) error { if needLock { w.Lock() @@ -420,7 +420,7 @@ func (w *Worker) StartSubTask(cfg *config.SubTaskConfig, expectStage pb.Stage, n return nil } -// UpdateSubTask update config for a sub task +// UpdateSubTask update config for a sub task. func (w *Worker) UpdateSubTask(cfg *config.SubTaskConfig) error { w.Lock() defer w.Unlock() @@ -438,7 +438,7 @@ func (w *Worker) UpdateSubTask(cfg *config.SubTaskConfig) error { return st.Update(cfg) } -// OperateSubTask stop/resume/pause sub task +// OperateSubTask stop/resume/pause sub task. func (w *Worker) OperateSubTask(name string, op pb.TaskOp) error { w.Lock() defer w.Unlock() @@ -476,7 +476,7 @@ func (w *Worker) OperateSubTask(name string, op pb.TaskOp) error { // QueryStatus query worker's sub tasks' status. If relay enabled, also return source status // TODO: `ctx` is used to get upstream master status in every subtasks and source. -// reduce it to only call once and remove `unifyMasterBinlogPos`, also remove below ctx2 +// reduce it to only call once and remove `unifyMasterBinlogPos`, also remove below ctx2. func (w *Worker) QueryStatus(ctx context.Context, name string) ([]*pb.SubTaskStatus, *pb.RelayStatus) { w.RLock() defer w.RUnlock() @@ -517,7 +517,6 @@ func (w *Worker) resetSubtaskStage() (int64, error) { opErrCounter.WithLabelValues(w.name, opType).Inc() log.L().Error("fail to operate subtask stage", zap.Stringer("stage", stage), zap.String("task", subtaskCfg.Name), zap.Error(err2)) - } delete(sts, name) } @@ -618,7 +617,7 @@ func (w *Worker) handleSubTaskStage(ctx context.Context, stageCh chan ha.Stage, } } -// operateSubTaskStage returns TaskOp.String() additionally to record metrics +// operateSubTaskStage returns TaskOp.String() additionally to record metrics. func (w *Worker) operateSubTaskStage(stage ha.Stage, subTaskCfg config.SubTaskConfig) (string, error) { var op pb.TaskOp switch { @@ -640,7 +639,7 @@ func (w *Worker) operateSubTaskStage(stage ha.Stage, subTaskCfg config.SubTaskCo return op.String(), w.OperateSubTask(stage.Task, op) } -// operateSubTaskStageWithoutConfig returns TaskOp additionally to record metrics +// operateSubTaskStageWithoutConfig returns TaskOp additionally to record metrics. func (w *Worker) operateSubTaskStageWithoutConfig(stage ha.Stage) (string, error) { var subTaskCfg config.SubTaskConfig if stage.Expect == pb.Stage_Running { @@ -746,7 +745,7 @@ OUTER: } // operateRelayStage returns RelayOp.String() additionally to record metrics -// *RelayOp is nil only when error is nil, so record on error will not meet nil-pointer deference +// *RelayOp is nil only when error is nil, so record on error will not meet nil-pointer deference. func (w *Worker) operateRelayStage(ctx context.Context, stage ha.Stage) (string, error) { var op pb.RelayOp switch { @@ -765,7 +764,7 @@ func (w *Worker) operateRelayStage(ctx context.Context, stage ha.Stage) (string, return op.String(), w.operateRelay(ctx, op) } -// OperateRelay operates relay unit +// OperateRelay operates relay unit. func (w *Worker) operateRelay(ctx context.Context, op pb.RelayOp) error { if w.closed.Get() { return terror.ErrWorkerAlreadyClosed.Generate() @@ -780,7 +779,7 @@ func (w *Worker) operateRelay(ctx context.Context, op pb.RelayOp) error { return nil } -// PurgeRelay purges relay log files +// PurgeRelay purges relay log files. func (w *Worker) PurgeRelay(ctx context.Context, req *pb.PurgeRelayRequest) error { if w.closed.Get() { return terror.ErrWorkerAlreadyClosed.Generate() @@ -817,7 +816,7 @@ func (w *Worker) PurgeRelay(ctx context.Context, req *pb.PurgeRelayRequest) erro return w.relayPurger.Do(ctx, req) } -// ForbidPurge implements PurgeInterceptor.ForbidPurge +// ForbidPurge implements PurgeInterceptor.ForbidPurge. func (w *Worker) ForbidPurge() (bool, string) { if w.closed.Get() { return false, "" @@ -852,7 +851,7 @@ func (w *Worker) OperateSchema(ctx context.Context, req *pb.OperateWorkerSchemaR return st.OperateSchema(ctx, req) } -// copyConfigFromSource copies config items from source config and worker's relayEnabled to sub task +// copyConfigFromSource copies config items from source config and worker's relayEnabled to sub task. func copyConfigFromSource(cfg *config.SubTaskConfig, sourceCfg *config.SourceConfig, enableRelay bool) error { cfg.From = sourceCfg.From @@ -888,7 +887,7 @@ func copyConfigFromSource(cfg *config.SubTaskConfig, sourceCfg *config.SourceCon return nil } -// copyConfigFromSourceForEach do copyConfigFromSource for each value in subTaskCfgM and change subTaskCfgM in-place +// copyConfigFromSourceForEach do copyConfigFromSource for each value in subTaskCfgM and change subTaskCfgM in-place. func copyConfigFromSourceForEach( subTaskCfgM map[string]config.SubTaskConfig, sourceCfg *config.SourceConfig, @@ -904,7 +903,7 @@ func copyConfigFromSourceForEach( } // getAllSubTaskStatus returns all subtask status of this worker, note the field -// in subtask status is not completed, only includes `Name`, `Stage` and `Result` now +// in subtask status is not completed, only includes `Name`, `Stage` and `Result` now. func (w *Worker) getAllSubTaskStatus() map[string]*pb.SubTaskStatus { sts := w.subTaskHolder.getAllSubTasks() result := make(map[string]*pb.SubTaskStatus, len(sts)) @@ -920,7 +919,7 @@ func (w *Worker) getAllSubTaskStatus() map[string]*pb.SubTaskStatus { return result } -// HandleError handle worker error +// HandleError handle worker error. func (w *Worker) HandleError(ctx context.Context, req *pb.HandleWorkerErrorRequest) error { w.Lock() defer w.Unlock() diff --git a/dm/worker/worker_test.go b/dm/worker/worker_test.go index 8ae40a086b..81589a5c86 100644 --- a/dm/worker/worker_test.go +++ b/dm/worker/worker_test.go @@ -229,9 +229,7 @@ var _ = Suite(&testWorkerFunctionalities{}) func (t *testWorkerFunctionalities) SetUpSuite(c *C) { NewRelayHolder = NewDummyRelayHolder - NewSubTask = func(cfg *config.SubTaskConfig, etcdClient *clientv3.Client) *SubTask { - return NewRealSubTask(cfg, etcdClient) - } + NewSubTask = NewRealSubTask createUnits = func(cfg *config.SubTaskConfig, etcdClient *clientv3.Client) []unit.Unit { atomic.AddInt32(&t.createUnitCount, 1) mockDumper := NewMockUnit(pb.UnitType_Dump) diff --git a/dumpling/dumpling.go b/dumpling/dumpling.go index 5d7a07c1ea..bc4f82d060 100644 --- a/dumpling/dumpling.go +++ b/dumpling/dumpling.go @@ -36,7 +36,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// Dumpling dumps full data from a MySQL-compatible database +// Dumpling dumps full data from a MySQL-compatible database. type Dumpling struct { cfg *config.SubTaskConfig @@ -46,7 +46,7 @@ type Dumpling struct { closed sync2.AtomicBool } -// NewDumpling creates a new Dumpling +// NewDumpling creates a new Dumpling. func NewDumpling(cfg *config.SubTaskConfig) *Dumpling { m := &Dumpling{ cfg: cfg, @@ -55,7 +55,7 @@ func NewDumpling(cfg *config.SubTaskConfig) *Dumpling { return m } -// Init implements Unit.Init +// Init implements Unit.Init. func (m *Dumpling) Init(ctx context.Context) error { var err error m.dumpConfig, err = m.constructArgs() @@ -64,7 +64,7 @@ func (m *Dumpling) Init(ctx context.Context) error { return err } -// Process implements Unit.Process +// Process implements Unit.Process. func (m *Dumpling) Process(ctx context.Context, pr chan pb.ProcessResult) { dumplingExitWithErrorCounter.WithLabelValues(m.cfg.Name, m.cfg.SourceID).Add(0) @@ -145,7 +145,7 @@ func (m *Dumpling) Process(ctx context.Context, pr chan pb.ProcessResult) { } } -// Close implements Unit.Close +// Close implements Unit.Close. func (m *Dumpling) Close() { if m.closed.Get() { return @@ -156,7 +156,7 @@ func (m *Dumpling) Close() { m.closed.Set(true) } -// Pause implements Unit.Pause +// Pause implements Unit.Pause. func (m *Dumpling) Pause() { if m.closed.Get() { m.logger.Warn("try to pause, but already closed") @@ -165,7 +165,7 @@ func (m *Dumpling) Pause() { // do nothing, external will cancel the command (if running) } -// Resume implements Unit.Resume +// Resume implements Unit.Resume. func (m *Dumpling) Resume(ctx context.Context, pr chan pb.ProcessResult) { if m.closed.Get() { m.logger.Warn("try to resume, but already closed") @@ -175,29 +175,29 @@ func (m *Dumpling) Resume(ctx context.Context, pr chan pb.ProcessResult) { m.Process(ctx, pr) } -// Update implements Unit.Update +// Update implements Unit.Update. func (m *Dumpling) Update(cfg *config.SubTaskConfig) error { // not support update configuration now return nil } -// Status implements Unit.Status +// Status implements Unit.Status. func (m *Dumpling) Status(ctx context.Context) interface{} { // NOTE: try to add some status, like dumped file count return &pb.DumpStatus{} } -// Type implements Unit.Type +// Type implements Unit.Type. func (m *Dumpling) Type() pb.UnitType { return pb.UnitType_Dump } -// IsFreshTask implements Unit.IsFreshTask +// IsFreshTask implements Unit.IsFreshTask. func (m *Dumpling) IsFreshTask(ctx context.Context) (bool, error) { return true, nil } -// constructArgs constructs arguments for exec.Command +// constructArgs constructs arguments for exec.Command. func (m *Dumpling) constructArgs() (*export.Config, error) { cfg := m.cfg db := cfg.From @@ -276,7 +276,7 @@ func (m *Dumpling) constructArgs() (*export.Config, error) { } // detectSQLMode tries to detect SQL mode from upstream. If success, write it to LoaderConfig. -// Because loader will use this SQL mode, we need to treat disable `EscapeBackslash` when NO_BACKSLASH_ESCAPES +// Because loader will use this SQL mode, we need to treat disable `EscapeBackslash` when NO_BACKSLASH_ESCAPES. func (m *Dumpling) detectSQLMode(ctx context.Context) { baseDB, err := conn.DefaultDBProvider.Apply(m.cfg.From) if err != nil { diff --git a/dumpling/dumpling_test.go b/dumpling/dumpling_test.go index fbe6b816ba..e31957bff6 100644 --- a/dumpling/dumpling_test.go +++ b/dumpling/dumpling_test.go @@ -20,13 +20,14 @@ import ( "testing" "time" - "github.com/pingcap/dm/dm/config" - "github.com/pingcap/dm/dm/pb" - "github.com/pingcap/dm/pkg/log" "github.com/pingcap/dumpling/v4/export" "github.com/pingcap/failpoint" "github.com/pingcap/tidb-tools/pkg/filter" + "github.com/pingcap/dm/dm/config" + "github.com/pingcap/dm/dm/pb" + "github.com/pingcap/dm/pkg/log" + . "github.com/pingcap/check" ) diff --git a/dumpling/metrics.go b/dumpling/metrics.go index b1b5c0e3be..22bdd256cc 100644 --- a/dumpling/metrics.go +++ b/dumpling/metrics.go @@ -22,16 +22,14 @@ import ( "github.com/pingcap/dm/pkg/metricsproxy" ) -var ( - // should alert - dumplingExitWithErrorCounter = metricsproxy.NewCounterVec( - prometheus.CounterOpts{ - Namespace: "dm", - Subsystem: "dumpling", - Name: "exit_with_error_count", - Help: "counter for dumpling exit with error", - }, []string{"task", "source_id"}) -) +// should alert. +var dumplingExitWithErrorCounter = metricsproxy.NewCounterVec( + prometheus.CounterOpts{ + Namespace: "dm", + Subsystem: "dumpling", + Name: "exit_with_error_count", + Help: "counter for dumpling exit with error", + }, []string{"task", "source_id"}) // RegisterMetrics registers metrics and saves the given registry for later use. func RegisterMetrics(registry *prometheus.Registry) { diff --git a/dumpling/util.go b/dumpling/util.go index 41cbad1ef7..c7c7a114e2 100644 --- a/dumpling/util.go +++ b/dumpling/util.go @@ -28,7 +28,7 @@ import ( ) // ParseArgLikeBash parses list arguments like bash, which helps us to run -// executable command via os/exec more likely running from bash +// executable command via os/exec more likely running from bash. func ParseArgLikeBash(args []string) []string { result := make([]string, 0, len(args)) for _, arg := range args { @@ -38,7 +38,7 @@ func ParseArgLikeBash(args []string) []string { return result } -// trimOutQuotes trims a pair of single quotes or a pair of double quotes from arg +// trimOutQuotes trims a pair of single quotes or a pair of double quotes from arg. func trimOutQuotes(arg string) string { argLen := len(arg) if argLen >= 2 { diff --git a/dumpling/util_test.go b/dumpling/util_test.go index c093ec2ef2..8c63b152ac 100644 --- a/dumpling/util_test.go +++ b/dumpling/util_test.go @@ -25,13 +25,13 @@ import ( "github.com/pingcap/dm/pkg/log" ) -func (m *testDumplingSuite) TestParseArgs(c *C) { +func (d *testDumplingSuite) TestParseArgs(c *C) { logger := log.L() cfg := &config.SubTaskConfig{} cfg.ExtraArgs = `--statement-size=100 --where "t>10" --threads 8 -F 50B` - d := NewDumpling(cfg) - exportCfg, err := d.constructArgs() + dumpling := NewDumpling(cfg) + exportCfg, err := dumpling.constructArgs() c.Assert(err, IsNil) c.Assert(exportCfg.StatementSize, Equals, uint64(100)) c.Assert(exportCfg.Where, Equals, "t>10") @@ -90,7 +90,7 @@ func (m *testDumplingSuite) TestParseArgs(c *C) { c.Assert(err.Error(), Equals, "cannot both specify `--no-locks` and `--consistency` other than `none`") } -func (m *testDumplingSuite) TestParseArgsWontOverwrite(c *C) { +func (d *testDumplingSuite) TestParseArgsWontOverwrite(c *C) { cfg := &config.SubTaskConfig{} cfg.ChunkFilesize = "1" rules := &filter.Rules{ @@ -100,8 +100,8 @@ func (m *testDumplingSuite) TestParseArgsWontOverwrite(c *C) { // make sure we enter `parseExtraArgs` cfg.ExtraArgs = "-s=4000 --consistency lock" - d := NewDumpling(cfg) - exportCfg, err := d.constructArgs() + dumpling := NewDumpling(cfg) + exportCfg, err := dumpling.constructArgs() c.Assert(err, IsNil) c.Assert(exportCfg.StatementSize, Equals, uint64(4000)) diff --git a/loader/checkpoint.go b/loader/checkpoint.go index 1305fc56c4..40dba78186 100644 --- a/loader/checkpoint.go +++ b/loader/checkpoint.go @@ -31,7 +31,7 @@ import ( "go.uber.org/zap" ) -// CheckPoint represents checkpoint status +// CheckPoint represents checkpoint status. type CheckPoint interface { // Load loads all checkpoints recorded before. // because of no checkpoints updated in memory when error occurred @@ -80,7 +80,7 @@ type CheckPoint interface { } // RemoteCheckPoint implements CheckPoint by saving status in remote database system, mostly in TiDB. -// it's not thread-safe +// it's not thread-safe. type RemoteCheckPoint struct { // used to protect database operation with `conn`. // if more operations need to be protected, add another mutex or rename this one. @@ -161,7 +161,7 @@ func (cp *RemoteCheckPoint) createTable(tctx *tcontext.Context) error { return terror.WithScope(err, terror.ScopeDownstream) } -// Load implements CheckPoint.Load +// Load implements CheckPoint.Load. func (cp *RemoteCheckPoint) Load(tctx *tcontext.Context) error { begin := time.Now() defer func() { @@ -208,7 +208,7 @@ func (cp *RemoteCheckPoint) Load(tctx *tcontext.Context) error { return terror.WithScope(terror.DBErrorAdapt(rows.Err(), terror.ErrDBDriverError), terror.ScopeDownstream) } -// GetRestoringFileInfo implements CheckPoint.GetRestoringFileInfo +// GetRestoringFileInfo implements CheckPoint.GetRestoringFileInfo. func (cp *RemoteCheckPoint) GetRestoringFileInfo(db, table string) map[string][]int64 { cp.restoringFiles.RLock() defer cp.restoringFiles.RUnlock() @@ -226,7 +226,7 @@ func (cp *RemoteCheckPoint) GetRestoringFileInfo(db, table string) map[string][] return results } -// GetAllRestoringFileInfo implements CheckPoint.GetAllRestoringFileInfo +// GetAllRestoringFileInfo implements CheckPoint.GetAllRestoringFileInfo. func (cp *RemoteCheckPoint) GetAllRestoringFileInfo() map[string][]int64 { cp.restoringFiles.RLock() defer cp.restoringFiles.RUnlock() @@ -242,7 +242,7 @@ func (cp *RemoteCheckPoint) GetAllRestoringFileInfo() map[string][]int64 { return results } -// IsTableCreated implements CheckPoint.IsTableCreated +// IsTableCreated implements CheckPoint.IsTableCreated. func (cp *RemoteCheckPoint) IsTableCreated(db, table string) bool { cp.restoringFiles.RLock() defer cp.restoringFiles.RUnlock() @@ -257,7 +257,7 @@ func (cp *RemoteCheckPoint) IsTableCreated(db, table string) bool { return ok } -// IsTableFinished implements CheckPoint.IsTableFinished +// IsTableFinished implements CheckPoint.IsTableFinished. func (cp *RemoteCheckPoint) IsTableFinished(db, table string) bool { key := strings.Join([]string{db, table}, ".") if _, ok := cp.finishedTables[key]; ok { @@ -266,7 +266,7 @@ func (cp *RemoteCheckPoint) IsTableFinished(db, table string) bool { return false } -// CalcProgress implements CheckPoint.CalcProgress +// CalcProgress implements CheckPoint.CalcProgress. func (cp *RemoteCheckPoint) CalcProgress(allFiles map[string]Tables2DataFiles) error { cp.restoringFiles.RLock() defer cp.restoringFiles.RUnlock() @@ -315,7 +315,7 @@ func (cp *RemoteCheckPoint) allFilesFinished(files map[string][]int64) bool { return true } -// AllFinished implements CheckPoint.AllFinished +// AllFinished implements CheckPoint.AllFinished. func (cp *RemoteCheckPoint) AllFinished() bool { cp.restoringFiles.RLock() defer cp.restoringFiles.RUnlock() @@ -329,13 +329,12 @@ func (cp *RemoteCheckPoint) AllFinished() bool { return true } -// Init implements CheckPoint.Init +// Init implements CheckPoint.Init. func (cp *RemoteCheckPoint) Init(tctx *tcontext.Context, filename string, endPos int64) error { // fields[0] -> db name, fields[1] -> table name schema, table, err := getDBAndTableFromFilename(filename) if err != nil { return terror.ErrCheckpointInvalidTableFile.Generate(filename) - } sql2 := fmt.Sprintf("INSERT INTO %s (`id`, `filename`, `cp_schema`, `cp_table`, `offset`, `end_pos`) VALUES(?,?,?,?,?,?)", cp.tableName) cp.logger.Info("initial checkpoint record", @@ -374,29 +373,28 @@ func (cp *RemoteCheckPoint) Init(tctx *tcontext.Context, filename string, endPos return nil } -// ResetConn implements CheckPoint.ResetConn +// ResetConn implements CheckPoint.ResetConn. func (cp *RemoteCheckPoint) ResetConn(tctx *tcontext.Context) error { cp.connMutex.Lock() defer cp.connMutex.Unlock() return cp.conn.resetConn(tctx) } -// Close implements CheckPoint.Close +// Close implements CheckPoint.Close. func (cp *RemoteCheckPoint) Close() { - err := cp.db.Close() - if err != nil { + if err := cp.db.Close(); err != nil { cp.logger.Error("close checkpoint db", log.ShortError(err)) } } -// GenSQL implements CheckPoint.GenSQL +// GenSQL implements CheckPoint.GenSQL. func (cp *RemoteCheckPoint) GenSQL(filename string, offset int64) string { sql := fmt.Sprintf("UPDATE %s SET `offset`=%d WHERE `id` ='%s' AND `filename`='%s';", cp.tableName, offset, cp.id, filename) return sql } -// UpdateOffset implements CheckPoint.UpdateOffset +// UpdateOffset implements CheckPoint.UpdateOffset. func (cp *RemoteCheckPoint) UpdateOffset(filename string, offset int64) { cp.restoringFiles.Lock() defer cp.restoringFiles.Unlock() @@ -408,7 +406,7 @@ func (cp *RemoteCheckPoint) UpdateOffset(filename string, offset int64) { cp.restoringFiles.pos[db][table][filename][0] = offset } -// Clear implements CheckPoint.Clear +// Clear implements CheckPoint.Clear. func (cp *RemoteCheckPoint) Clear(tctx *tcontext.Context) error { sql2 := fmt.Sprintf("DELETE FROM %s WHERE `id` = '%s'", cp.tableName, cp.id) cp.connMutex.Lock() @@ -417,7 +415,7 @@ func (cp *RemoteCheckPoint) Clear(tctx *tcontext.Context) error { return terror.WithScope(err, terror.ScopeDownstream) } -// Count implements CheckPoint.Count +// Count implements CheckPoint.Count. func (cp *RemoteCheckPoint) Count(tctx *tcontext.Context) (int, error) { query := fmt.Sprintf("SELECT COUNT(id) FROM %s WHERE `id` = ?", cp.tableName) cp.connMutex.Lock() @@ -427,7 +425,7 @@ func (cp *RemoteCheckPoint) Count(tctx *tcontext.Context) (int, error) { return 0, terror.WithScope(err, terror.ScopeDownstream) } defer rows.Close() - var count = 0 + count := 0 for rows.Next() { err = rows.Scan(&count) if err != nil { diff --git a/loader/checkpoint_test.go b/loader/checkpoint_test.go index 7062f3d5f5..30cfacb1e0 100644 --- a/loader/checkpoint_test.go +++ b/loader/checkpoint_test.go @@ -59,7 +59,7 @@ func (t *testCheckPointSuite) SetUpSuite(c *C) { func (t *testCheckPointSuite) TearDownSuite(c *C) { } -// test checkpoint's db operation +// test checkpoint's db operation. func (t *testCheckPointSuite) TestForDB(c *C) { cases := []struct { filename string diff --git a/loader/convert_data.go b/loader/convert_data.go index 66a96cebaa..9d3e899f1b 100644 --- a/loader/convert_data.go +++ b/loader/convert_data.go @@ -40,11 +40,11 @@ func bytes2str(bs []byte) string { // poor man's parse insert stmtement code // learn from tidb-lightning and refactor it as format of mydumper file // https://github.com/maxbube/mydumper/blob/master/mydumper.c#L2853 -// later let it a package +// later let it a package. func parseInsertStmt(sql []byte, table *tableInfo, columnMapping *cm.Mapping) ([][]string, error) { var s, e, size int - var rows = make([][]string, 0, 1024) - var VALUES = []byte("VALUES") + rows := make([][]string, 0, 1024) + VALUES := []byte("VALUES") // If table has generated column, the dumped SQL file has a different `INSERT INTO` line, // which provides column names except generated column. such as following: @@ -132,6 +132,7 @@ func parseRowValues(str []byte, table *tableInfo, columnMapping *cm.Mapping) ([] sch := ch for j < size { + // nolint:gocritic if str[j] == '\\' { // skip escaped character j += 2 @@ -178,13 +179,12 @@ func parseRowValues(str []byte, table *tableInfo, columnMapping *cm.Mapping) ([] } else { row = append(row, val) } - } return row, nil } -// exportStatement returns schema structure in sqlFile +// exportStatement returns schema structure in sqlFile. func exportStatement(sqlFile string) ([]byte, error) { fd, err := os.Open(sqlFile) if err != nil { @@ -297,7 +297,7 @@ func parseTable(ctx *tcontext.Context, r *router.Table, schema, table, file stri }, nil } -// refine it later +// refine it later. func reassemble(data []byte, table *tableInfo, columnMapping *cm.Mapping) (string, error) { rows, err := parseInsertStmt(data, table, columnMapping) if err != nil { diff --git a/loader/convert_data_test.go b/loader/convert_data_test.go index c302fdaa38..f3bee25e8d 100644 --- a/loader/convert_data_test.go +++ b/loader/convert_data_test.go @@ -14,11 +14,12 @@ package loader import ( - tcontext "github.com/pingcap/dm/pkg/context" cm "github.com/pingcap/tidb-tools/pkg/column-mapping" + router "github.com/pingcap/tidb-tools/pkg/table-router" + + tcontext "github.com/pingcap/dm/pkg/context" . "github.com/pingcap/check" - "github.com/pingcap/tidb-tools/pkg/table-router" ) var _ = Suite(&testConvertDataSuite{}) @@ -53,6 +54,7 @@ func (t *testConvertDataSuite) TestReassemble(c *C) { insertHeadStmt: "INSERT INTO t VALUES", } + // nolint:stylecheck sql := `INSERT INTO t1 VALUES (10,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"x","x\"x","blob","text","enum2","a,b"), (9,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"x","x\",\nx","blob","text","enum2","a,b"); @@ -60,7 +62,9 @@ func (t *testConvertDataSuite) TestReassemble(c *C) { ` expected := []string{ + // nolint:stylecheck `INSERT INTO t VALUES(585520728116297738,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"x","x\"x","blob","text","enum2","a,b"),(585520728116297737,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"x","x\",\nx","blob","text","enum2","a,b"),(585520728116297736,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"x","x\",\nx","blob"," text\n","enum2"," a,b ");`, + // nolint:stylecheck `INSERT INTO t VALUES(10,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"test:x","x\"x","blob","text","enum2","a,b"),(9,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"test:x","x\",\nx","blob","text","enum2","a,b"),(8,1,9223372036854775807,123.123,123456789012.1234567890120000000,"\0\0\0\0\0\0\0A","1000-01-01","9999-12-31 23:59:59","1973-12-30 15:30:00","23:59:59",1970,"test:x","x\",\nx","blob"," text\n","enum2"," a,b ");`, } diff --git a/loader/db.go b/loader/db.go index 90d7288658..e7a6590b71 100644 --- a/loader/db.go +++ b/loader/db.go @@ -35,7 +35,7 @@ import ( ) // DBConn represents a live DB connection -// it's not thread-safe +// it's not thread-safe. type DBConn struct { cfg *config.SubTaskConfig baseConn *conn.BaseConn @@ -83,6 +83,9 @@ func (conn *DBConn) querySQL(ctx *tcontext.Context, query string, args ...interf startTime := time.Now() ret, err := conn.baseConn.QuerySQL(ctx, query, args...) if err == nil { + if ret.Err() != nil { + return ret, ret.Err() + } cost := time.Since(startTime) queryHistogram.WithLabelValues(conn.cfg.Name, conn.cfg.SourceID).Observe(cost.Seconds()) if cost.Seconds() > 1 { @@ -170,7 +173,6 @@ func (conn *DBConn) executeSQL(ctx *tcontext.Context, queries []string, args ... } return nil, err }) - if err != nil { ctx.L().ErrorFilterContextCanceled("execute statements failed after retry", zap.String("queries", utils.TruncateInterface(queries, -1)), @@ -181,7 +183,7 @@ func (conn *DBConn) executeSQL(ctx *tcontext.Context, queries []string, args ... return err } -// resetConn reset one worker connection from specify *BaseDB +// resetConn reset one worker connection from specify *BaseDB. func (conn *DBConn) resetConn(tctx *tcontext.Context) error { baseConn, err := conn.resetBaseConnFn(tctx, conn.baseConn) if err != nil { diff --git a/loader/loader.go b/loader/loader.go index c59391eaeb..8c0c3574d3 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -27,6 +27,8 @@ import ( "sync/atomic" "time" + "golang.org/x/sync/errgroup" + "github.com/pingcap/dm/dm/config" "github.com/pingcap/dm/dm/pb" "github.com/pingcap/dm/dm/unit" @@ -37,7 +39,6 @@ import ( "github.com/pingcap/dm/pkg/log" "github.com/pingcap/dm/pkg/terror" "github.com/pingcap/dm/pkg/utils" - "golang.org/x/sync/errgroup" "github.com/pingcap/errors" "github.com/pingcap/failpoint" @@ -56,10 +57,10 @@ const ( // FilePosSet represents a set in mathematics. type FilePosSet map[string][]int64 -// DataFiles represent all data files for a single table +// DataFiles represent all data files for a single table. type DataFiles []string -// Tables2DataFiles represent all data files of a table collection as a map +// Tables2DataFiles represent all data files of a table collection as a map. type Tables2DataFiles map[string]DataFiles type dataJob struct { @@ -116,7 +117,7 @@ func NewWorker(loader *Loader, id int) *Worker { return w } -// Close closes worker +// Close closes worker. func (w *Worker) Close() { // simulate the case that doesn't wait all doJob goroutine exit failpoint.Inject("workerCantClose", func(_ failpoint.Value) { @@ -367,7 +368,6 @@ func (w *Worker) dispatchSQL(ctx context.Context, file string, offset int64, tab w.jobQueue <- j } - } return nil @@ -396,20 +396,12 @@ type Loader struct { db2Tables map[string]Tables2DataFiles tableInfos map[string]*tableInfo - // for every worker goroutine, not for every data file - workerWg *sync.WaitGroup - // for other goroutines - wg sync.WaitGroup - - fileJobQueue chan *fileJob - fileJobQueueClosed sync2.AtomicBool + fileJobQueue chan *fileJob tableRouter *router.Table baList *filter.Filter columnMapping *cm.Mapping - closed sync2.AtomicBool - toDB *conn.BaseDB toDBConns []*DBConn @@ -422,7 +414,14 @@ type Loader struct { // record process error rather than log.Fatal runFatalChan chan *pb.ProcessError - finish sync2.AtomicBool + // for every worker goroutine, not for every data file + workerWg *sync.WaitGroup + // for other goroutines + wg sync.WaitGroup + + fileJobQueueClosed sync2.AtomicBool + finish sync2.AtomicBool + closed sync2.AtomicBool } // NewLoader creates a new Loader. @@ -438,7 +437,7 @@ func NewLoader(cfg *config.SubTaskConfig) *Loader { return loader } -// Type implements Unit.Type +// Type implements Unit.Type. func (l *Loader) Type() pb.UnitType { return pb.UnitType_Load } @@ -517,7 +516,7 @@ func (l *Loader) Init(ctx context.Context) (err error) { return nil } -// Process implements Unit.Process +// Process implements Unit.Process. func (l *Loader) Process(ctx context.Context, pr chan pb.ProcessResult) { loaderExitWithErrorCounter.WithLabelValues(l.cfg.Name, l.cfg.SourceID).Add(0) @@ -598,7 +597,7 @@ func (l *Loader) closeFileJobQueue() { } // align with https://github.com/pingcap/dumpling/pull/140 -// if input is malformed, return original string and print log +// if input is malformed, return original string and print log. func unescapePercent(input string, logger log.Logger) string { buf := bytes.Buffer{} buf.Grow(len(input)) @@ -618,7 +617,7 @@ func unescapePercent(input string, logger log.Logger) string { return input } buf.Write(ascii) - i = i + 3 + i += 3 } } return buf.String() @@ -641,7 +640,7 @@ func (l *Loader) isClosed() bool { return l.closed.Get() } -// IsFreshTask implements Unit.IsFreshTask +// IsFreshTask implements Unit.IsFreshTask. func (l *Loader) IsFreshTask(ctx context.Context) (bool, error) { count, err := l.checkPoint.Count(tcontext.NewContext(ctx, l.logger)) return count == 0, err @@ -721,7 +720,7 @@ func (l *Loader) loadFinishedSize() { } } -// Close does graceful shutdown +// Close does graceful shutdown. func (l *Loader) Close() { l.Lock() defer l.Unlock() @@ -731,8 +730,7 @@ func (l *Loader) Close() { l.stopLoad() - err := l.toDB.Close() - if err != nil { + if err := l.toDB.Close(); err != nil { l.logger.Error("close downstream DB error", log.ShortError(err)) } l.checkPoint.Close() @@ -741,7 +739,7 @@ func (l *Loader) Close() { } // stopLoad stops loading, now it used by Close and Pause -// maybe we can refine the workflow more clear +// maybe we can refine the workflow more clear. func (l *Loader) stopLoad() { // before re-write workflow, simply close all job queue and job workers // when resuming, re-create them @@ -756,7 +754,7 @@ func (l *Loader) stopLoad() { } // Pause pauses the process, and it can be resumed later -// should cancel context from external +// should cancel context from external. func (l *Loader) Pause() { if l.isClosed() { l.logger.Warn("try to pause, but already closed") @@ -766,15 +764,14 @@ func (l *Loader) Pause() { l.stopLoad() } -// Resume resumes the paused process +// Resume resumes the paused process. func (l *Loader) Resume(ctx context.Context, pr chan pb.ProcessResult) { if l.isClosed() { l.logger.Warn("try to resume, but already closed") return } - err := l.resetDBs(ctx) - if err != nil { + if err := l.resetDBs(ctx); err != nil { pr <- pb.ProcessResult{ IsCanceled: false, Errors: []*pb.ProcessError{ @@ -809,7 +806,7 @@ func (l *Loader) resetDBs(ctx context.Context) error { // Update implements Unit.Update // now, only support to update config for routes, filters, column-mappings, block-allow-list // now no config diff implemented, so simply re-init use new config -// no binlog filter for loader need to update +// no binlog filter for loader need to update. func (l *Loader) Update(cfg *config.SubTaskConfig) error { var ( err error @@ -886,7 +883,7 @@ func (l *Loader) initAndStartWorkerPool(ctx context.Context) error { return nil } -func (l *Loader) prepareDbFiles(files map[string]struct{}) error { +func (l *Loader) prepareDBFiles(files map[string]struct{}) error { // reset some variables l.db2Tables = make(map[string]Tables2DataFiles) l.totalFileCount.Set(0) // reset @@ -1055,7 +1052,7 @@ func (l *Loader) prepare() error { */ // Sql file for create db - if err := l.prepareDbFiles(files); err != nil { + if err := l.prepareDBFiles(files); err != nil { return err } @@ -1068,7 +1065,7 @@ func (l *Loader) prepare() error { return l.prepareDataFiles(files) } -// restoreSchema creates schema +// restoreSchema creates schema. func (l *Loader) restoreSchema(ctx context.Context, conn *DBConn, sqlFile, schema string) error { if l.checkPoint.IsTableCreated(schema, "") { l.logger.Info("database already exists in checkpoint, skip creating it", zap.String("schema", schema), zap.String("db schema file", sqlFile)) @@ -1085,7 +1082,7 @@ func (l *Loader) restoreSchema(ctx context.Context, conn *DBConn, sqlFile, schem return nil } -// restoreTable creates table +// restoreTable creates table. func (l *Loader) restoreTable(ctx context.Context, conn *DBConn, sqlFile, schema, table string) error { if l.checkPoint.IsTableCreated(schema, table) { l.logger.Info("table already exists in checkpoint, skip creating it", zap.String("schema", schema), zap.String("table", table), zap.String("db schema file", sqlFile)) @@ -1102,7 +1099,7 @@ func (l *Loader) restoreTable(ctx context.Context, conn *DBConn, sqlFile, schema return nil } -// restoreStruture creates schema or table +// restoreStruture creates schema or table. func (l *Loader) restoreStructure(ctx context.Context, conn *DBConn, sqlFile string, schema string, table string) error { f, err := os.Open(sqlFile) if err != nil { @@ -1157,12 +1154,12 @@ func (l *Loader) restoreStructure(ctx context.Context, conn *DBConn, sqlFile str return nil } -// renameShardingTable replaces srcTable with dstTable in query +// renameShardingTable replaces srcTable with dstTable in query. func renameShardingTable(query, srcTable, dstTable string, ansiquote bool) string { return SQLReplace(query, srcTable, dstTable, ansiquote) } -// renameShardingSchema replaces srcSchema with dstSchema in query +// renameShardingSchema replaces srcSchema with dstSchema in query. func renameShardingSchema(query, srcSchema, dstSchema string, ansiquote bool) string { return SQLReplace(query, srcSchema, dstSchema, ansiquote) } @@ -1189,7 +1186,7 @@ func fetchMatchedLiteral(ctx *tcontext.Context, router *router.Table, schema, ta return targetSchema, targetTable } -// `restore Schema Job` present a data structure of schema restoring job +// `restore Schema Job` present a data structure of schema restoring job. type restoreSchemaJob struct { loader *Loader session *DBConn @@ -1198,7 +1195,7 @@ type restoreSchemaJob struct { filepath string // file path of dumpped schema file } -// `jobQueue` of schema restoring which (only) support consumptions concurrently +// `jobQueue` of schema restoring which (only) support consumptions concurrently. type jobQueue struct { ctx context.Context msgq chan *restoreSchemaJob // job message queue channel @@ -1206,7 +1203,7 @@ type jobQueue struct { eg *errgroup.Group // err wait group of consumer's go-routines } -// `newJobQueue` consturct a jobQueue +// `newJobQueue` consturct a jobQueue. func newJobQueue(ctx context.Context, consumerCount, length int) *jobQueue { eg, selfCtx := errgroup.WithContext(ctx) return &jobQueue{ @@ -1217,7 +1214,7 @@ func newJobQueue(ctx context.Context, consumerCount, length int) *jobQueue { } } -// `push` will append a job to the queue +// `push` will append a job to the queue. func (q *jobQueue) push(job *restoreSchemaJob) error { var err error select { @@ -1228,7 +1225,7 @@ func (q *jobQueue) push(job *restoreSchemaJob) error { return terror.WithScope(err, terror.ScopeInternal) } -// `close` wait jobs done and close queue forever +// `close` wait jobs done and close queue forever. func (q *jobQueue) close() error { // queue is closing close(q.msgq) @@ -1236,7 +1233,7 @@ func (q *jobQueue) close() error { return q.eg.Wait() } -// `startConsumers` run multiple go-routines of job consumption with user defined handler +// `startConsumers` run multiple go-routines of job consumption with user defined handler. func (q *jobQueue) startConsumers(handler func(ctx context.Context, job *restoreSchemaJob) error) { for i := 0; i < q.consumerCount; i++ { q.eg.Go(func() error { @@ -1254,14 +1251,14 @@ func (q *jobQueue) startConsumers(handler func(ctx context.Context, job *restore // test condition for `job.session` means db session still could be controlled outside, // it's used in unit test for now. if session == nil && job.session == nil { - baseConn, err := job.loader.toDB.GetBaseConn(q.ctx) - if err != nil { - return err + baseConn, err2 := job.loader.toDB.GetBaseConn(q.ctx) + if err2 != nil { + return err2 } defer func(baseConn *conn.BaseConn) { - err := job.loader.toDB.CloseBaseConn(baseConn) - if err != nil { - job.loader.logger.Warn("fail to close connection", zap.Error(err)) + err2 := job.loader.toDB.CloseBaseConn(baseConn) + if err2 != nil { + job.loader.logger.Warn("fail to close connection", zap.Error(err2)) } }(baseConn) session = &DBConn{ @@ -1444,7 +1441,7 @@ tblSchemaLoop: return nil } -// checkpointID returns ID which used for checkpoint table +// checkpointID returns ID which used for checkpoint table. func (l *Loader) checkpointID() string { if len(l.cfg.SourceID) > 0 { return l.cfg.SourceID @@ -1479,7 +1476,7 @@ func (l *Loader) getMydumpMetadata() error { return nil } -// cleanDumpFiles is called when finish restoring data, to clean useless files +// cleanDumpFiles is called when finish restoring data, to clean useless files. func (l *Loader) cleanDumpFiles() { l.logger.Info("clean dump files") if l.cfg.Mode == config.ModeFull { diff --git a/loader/metrics.go b/loader/metrics.go index fe830c0c49..49a659c520 100644 --- a/loader/metrics.go +++ b/loader/metrics.go @@ -20,7 +20,7 @@ import ( ) var ( - // should error + // should error. tidbExecutionErrorCounter = metricsproxy.NewCounterVec( prometheus.CounterOpts{ Namespace: "dm", @@ -88,7 +88,7 @@ var ( Help: "the processing progress of loader in percentage", }, []string{"task", "source_id"}) - // should alert + // should alert. loaderExitWithErrorCounter = metricsproxy.NewCounterVec( prometheus.CounterOpts{ Namespace: "dm", @@ -98,7 +98,7 @@ var ( }, []string{"task", "source_id"}) ) -// RegisterMetrics registers metrics +// RegisterMetrics registers metrics. func RegisterMetrics(registry *prometheus.Registry) { registry.MustRegister(tidbExecutionErrorCounter) registry.MustRegister(txnHistogram) @@ -111,7 +111,7 @@ func RegisterMetrics(registry *prometheus.Registry) { registry.MustRegister(loaderExitWithErrorCounter) } -func (m *Loader) removeLabelValuesWithTaskInMetrics(task string) { +func (l *Loader) removeLabelValuesWithTaskInMetrics(task string) { tidbExecutionErrorCounter.DeleteAllAboutLabels(prometheus.Labels{"task": task}) txnHistogram.DeleteAllAboutLabels(prometheus.Labels{"task": task}) queryHistogram.DeleteAllAboutLabels(prometheus.Labels{"task": task}) diff --git a/loader/status.go b/loader/status.go index 8c497cf998..8d247f3bf3 100644 --- a/loader/status.go +++ b/loader/status.go @@ -23,11 +23,9 @@ import ( "github.com/pingcap/dm/dm/pb" ) -var ( - printStatusInterval = time.Second * 5 -) +var printStatusInterval = time.Second * 5 -// Status implements Unit.Status +// Status implements Unit.Status. func (l *Loader) Status(ctx context.Context) interface{} { finishedSize := l.finishedDataSize.Get() totalSize := l.totalDataSize.Get() diff --git a/loader/util.go b/loader/util.go index f1a8855fea..9c5d136025 100644 --- a/loader/util.go +++ b/loader/util.go @@ -24,12 +24,12 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// CollectDirFiles gets files in path +// CollectDirFiles gets files in path. func CollectDirFiles(path string) (map[string]struct{}, error) { files := make(map[string]struct{}) err := filepath.Walk(path, func(_ string, f os.FileInfo, err error) error { if err != nil { - return nil + return err } if f == nil { @@ -50,7 +50,7 @@ func CollectDirFiles(path string) (map[string]struct{}, error) { // SQLReplace works like strings.Replace but only supports one replacement. // It uses backquote pairs to quote the old and new word. -func SQLReplace(s, old, new string, ansiquote bool) string { +func SQLReplace(s, oldStr, newStr string, ansiquote bool) string { var quote string if ansiquote { quote = "\"" @@ -65,15 +65,15 @@ func SQLReplace(s, old, new string, ansiquote bool) string { return b.String() } - old = quoteF(old) - new = quoteF(new) - return strings.Replace(s, old, new, 1) + oldStr = quoteF(oldStr) + newStr = quoteF(newStr) + return strings.Replace(s, oldStr, newStr, 1) } -// shortSha1 returns the first 6 characters of sha1 value +// shortSha1 returns the first 6 characters of sha1 value. func shortSha1(s string) string { h := sha1.New() - //nolint:errcheck + h.Write([]byte(s)) return fmt.Sprintf("%x", h.Sum(nil))[:6] } @@ -112,10 +112,10 @@ func generateSchemaCreateFile(dir string, schema string) error { } func escapeName(name string) string { - return strings.Replace(name, "`", "``", -1) + return strings.ReplaceAll(name, "`", "``") } -// input filename is like `all_mode.t1.0.sql` or `all_mode.t1.sql` +// input filename is like `all_mode.t1.0.sql` or `all_mode.t1.sql`. func getDBAndTableFromFilename(filename string) (string, string, error) { idx := strings.LastIndex(filename, ".sql") if idx < 0 { diff --git a/loader/util_test.go b/loader/util_test.go index cc5bc4d0b5..64fa7725f7 100644 --- a/loader/util_test.go +++ b/loader/util_test.go @@ -32,8 +32,7 @@ var _ = Suite(&testUtilSuite{}) type testUtilSuite struct{} func (t *testUtilSuite) TestSQLReplace(c *C) { - - var replaceTests = []struct { + replaceTests := []struct { in string old, new string out string diff --git a/monitoring/dashboards/dashboard.go b/monitoring/dashboards/dashboard.go index ac6f0421b4..9898ee6642 100644 --- a/monitoring/dashboards/dashboard.go +++ b/monitoring/dashboards/dashboard.go @@ -18,11 +18,9 @@ const ( name = "dm.json" ) -var ( - dashboards = map[string]string{ - "dm.json": "Test-Cluster-DM", - } -) +var dashboards = map[string]string{ + "dm.json": "Test-Cluster-DM", +} func readDashboard(dir string, name string) (string, error) { file := filepath.Join(dir, name) @@ -39,7 +37,7 @@ func writeDashboard(dir string, name string, body string) error { return errors.Errorf("%s dashboard is not found in operator", name) } - writeFile(dir, name, filterDashboard(body, name, title)) + writeFile(dir, name, filterDashboard(body, title)) return nil } @@ -64,7 +62,7 @@ func checkErr(err error, msg string) { } } -func filterDashboard(str string, dashboard string, title string) string { +func filterDashboard(str string, title string) string { // replace grafana item var err error r := gjson.Get(str, "__requires.0.type") diff --git a/pkg/atomic2/atomic.go b/pkg/atomic2/atomic.go index 5168ff03d6..9b844f9b6b 100644 --- a/pkg/atomic2/atomic.go +++ b/pkg/atomic2/atomic.go @@ -18,40 +18,38 @@ import ( "unsafe" ) -// AtomicError implements atomic error method +// AtomicError implements atomic error method. type AtomicError struct { p unsafe.Pointer } -// Get returns error +// Get returns error. func (e *AtomicError) Get() error { - p := atomic.LoadPointer(&e.p) - if p == nil { - return nil + if p := atomic.LoadPointer(&e.p); p != nil { + return *(*error)(p) } - return *(*error)(p) + return nil } -// Set sets error to AtomicError +// Set sets error to AtomicError. func (e *AtomicError) Set(err error) { atomic.StorePointer(&e.p, unsafe.Pointer(&err)) } -// AtomicString implements atomic string method +// AtomicString implements atomic string method. type AtomicString struct { p unsafe.Pointer } -// Get returns string +// Get returns string. func (s *AtomicString) Get() string { - p := atomic.LoadPointer(&s.p) - if p == nil { - return "" + if p := atomic.LoadPointer(&s.p); p != nil { + return *(*string)(p) } - return *(*string)(p) + return "" } -// Set sets string to AtomicString +// Set sets string to AtomicString. func (s *AtomicString) Set(str string) { atomic.StorePointer(&s.p, unsafe.Pointer(&str)) } diff --git a/pkg/atomic2/atomic_test.go b/pkg/atomic2/atomic_test.go index 745ef48cb9..a997a21bc0 100644 --- a/pkg/atomic2/atomic_test.go +++ b/pkg/atomic2/atomic_test.go @@ -63,7 +63,8 @@ func (t *testAtomicSuite) TestAtomicString(c *C) { c.Assert(str2, Equals, str) originStr := str - str = "test2" //nolint:ineffassign + // nolint + str = "test2" str2 = s.Get() c.Assert(str2, Equals, originStr) diff --git a/pkg/backoff/backoff.go b/pkg/backoff/backoff.go index d3756443fe..3af54e4950 100644 --- a/pkg/backoff/backoff.go +++ b/pkg/backoff/backoff.go @@ -23,7 +23,7 @@ import ( // Backoff is an exponential counter, it starts from `Min` duration, and after // every call to `Duration` method the duration will be multiplied by `Factor`, -// but it never exceeds `Max`. Backoff is not thread-safe +// but it never exceeds `Max`. Backoff is not thread-safe. type Backoff struct { // cwnd is the congestion window cwnd int @@ -38,7 +38,7 @@ type Backoff struct { Min, Max time.Duration } -// NewBackoff creates a new backoff instance +// NewBackoff creates a new backoff instance. func NewBackoff(factor float64, jitter bool, min, max time.Duration) (*Backoff, error) { if factor <= 0 { return nil, terror.ErrBackoffArgsNotValid.Generate("factor", factor) @@ -57,7 +57,7 @@ func NewBackoff(factor float64, jitter bool, min, max time.Duration) (*Backoff, }, nil } -// Duration returns the duration for the current cwnd and increases the cwnd counter +// Duration returns the duration for the current cwnd and increases the cwnd counter. func (b *Backoff) Duration() time.Duration { d := b.Current() b.Forward() @@ -65,7 +65,7 @@ func (b *Backoff) Duration() time.Duration { } // Current returns the duration for the current cwnd, but doesn't increase the -// cwnd counter +// cwnd counter. func (b *Backoff) Current() time.Duration { return b.durationcwnd(b.cwnd) } @@ -78,13 +78,13 @@ func (b *Backoff) BoundaryForward() { } } -// Forward increases the cwnd counter +// Forward increases the cwnd counter. func (b *Backoff) Forward() { b.cwnd++ } // Rollback try to decrease cwnd by one if it is greater or equal than one. -// This is used for we have a long enough duration without backoff try +// This is used for we have a long enough duration without backoff try. func (b *Backoff) Rollback() { if b.cwnd > 0 { b.cwnd-- diff --git a/pkg/binlog/common/replication.go b/pkg/binlog/common/replication.go index fe1a1e16df..4123b5d117 100644 --- a/pkg/binlog/common/replication.go +++ b/pkg/binlog/common/replication.go @@ -20,7 +20,7 @@ import ( ) var ( - // MaxBinlogSyncerReconnect is the max reconnection times for binlog syncer in go-mysql + // MaxBinlogSyncerReconnect is the max reconnection times for binlog syncer in go-mysql. MaxBinlogSyncerReconnect = 60 // SlaveReadTimeout is slave read binlog data timeout, ref: https://dev.mysql.com/doc/refman/8.0/en/replication-options-slave.html#sysvar_slave_net_timeout SlaveReadTimeout = 1 * time.Minute @@ -29,7 +29,7 @@ var ( ) // SetDefaultReplicationCfg sets some default value for BinlogSyncerConfig -// Note: retryCount should be greater than 0, set retryCount = 1 if you want to disable retry sync +// Note: retryCount should be greater than 0, set retryCount = 1 if you want to disable retry sync. func SetDefaultReplicationCfg(cfg *replication.BinlogSyncerConfig, retryCount int) { cfg.UseDecimal = true // must set true. ref: https://github.com/pingcap/tidb-enterprise-tools/pull/272 cfg.VerifyChecksum = true diff --git a/pkg/binlog/common/replication_test.go b/pkg/binlog/common/replication_test.go index 04bb11d6c5..98f2e080b8 100644 --- a/pkg/binlog/common/replication_test.go +++ b/pkg/binlog/common/replication_test.go @@ -30,5 +30,4 @@ func (t *testCommonSuite) TestSetDefaultReplicationCfg(c *C) { SetDefaultReplicationCfg(&syncCfg, retryCnt) c.Assert(syncCfg.MaxReconnectAttempts, Equals, retryCnt) c.Assert(syncCfg.DisableRetrySync, IsTrue) - } diff --git a/pkg/binlog/common/stage_test.go b/pkg/binlog/common/stage_test.go index c68f6d0b70..253c1cff72 100644 --- a/pkg/binlog/common/stage_test.go +++ b/pkg/binlog/common/stage_test.go @@ -23,12 +23,9 @@ func TestSuite(t *testing.T) { TestingT(t) } -var ( - _ = Suite(&testCommonSuite{}) -) +var _ = Suite(&testCommonSuite{}) -type testCommonSuite struct { -} +type testCommonSuite struct{} func (t *testCommonSuite) TestStageString(c *C) { cases := []struct { diff --git a/pkg/binlog/event/common_test.go b/pkg/binlog/event/common_test.go index 4f8cf56a44..32f1b08c6b 100644 --- a/pkg/binlog/event/common_test.go +++ b/pkg/binlog/event/common_test.go @@ -27,8 +27,7 @@ import ( var _ = Suite(&testCommonSuite{}) -type testCommonSuite struct { -} +type testCommonSuite struct{} func (t *testCommonSuite) TestGenCommonFileHeader(c *C) { var ( @@ -56,7 +55,7 @@ func (t *testCommonSuite) TestGenCommonFileHeader(c *C) { _, err = mysqlFile.Write(data) c.Assert(err, IsNil) - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { count++ if count > 2 { @@ -103,7 +102,6 @@ func (t *testCommonSuite) TestGenCommonGTIDEvent(c *C) { var ( flavor = gmysql.MySQLFlavor serverID uint32 = 101 - gSetStr = "" gSet gtid.Set latestPos uint32 = 123 ) @@ -114,7 +112,7 @@ func (t *testCommonSuite) TestGenCommonGTIDEvent(c *C) { c.Assert(gtidEv, IsNil) // multi GTID in set, invalid - gSetStr = "03fc0263-28c7-11e7-a653-6c0b84d59f30:1-123,05474d3c-28c7-11e7-8352-203db246dd3d:1-456,10b039fc-c843-11e7-8f6a-1866daf8d810:1-789" + gSetStr := "03fc0263-28c7-11e7-a653-6c0b84d59f30:1-123,05474d3c-28c7-11e7-8352-203db246dd3d:1-456,10b039fc-c843-11e7-8f6a-1866daf8d810:1-789" gSet, err = gtid.ParserGTID(flavor, gSetStr) c.Assert(err, IsNil) gtidEv, err = GenCommonGTIDEvent(flavor, serverID, latestPos, gSet) diff --git a/pkg/binlog/event/ddl_test.go b/pkg/binlog/event/ddl_test.go index e28f366812..6b77724d79 100644 --- a/pkg/binlog/event/ddl_test.go +++ b/pkg/binlog/event/ddl_test.go @@ -25,8 +25,7 @@ import ( var _ = Suite(&testDDLSuite{}) -type testDDLSuite struct { -} +type testDDLSuite struct{} func (t *testDDLSuite) TestGenDDLEvent(c *C) { var ( diff --git a/pkg/binlog/event/dml_test.go b/pkg/binlog/event/dml_test.go index 710bc38ae2..e24811da49 100644 --- a/pkg/binlog/event/dml_test.go +++ b/pkg/binlog/event/dml_test.go @@ -25,8 +25,7 @@ import ( var _ = Suite(&testDMLSuite{}) -type testDMLSuite struct { -} +type testDMLSuite struct{} func (t *testDMLSuite) TestGenDMLEvent(c *C) { var ( diff --git a/pkg/binlog/event/event.go b/pkg/binlog/event/event.go index e4efe30c16..cbe58705bf 100644 --- a/pkg/binlog/event/event.go +++ b/pkg/binlog/event/event.go @@ -47,9 +47,9 @@ const ( crc32Len uint32 = 4 // CRC32-length tableMapFlags uint16 = 1 // flags in TableMapEvent's post-header, not used yet - // MinUserVarEventLen represents the minimum event length for a USER_VAR_EVENT with checksum + // MinUserVarEventLen represents the minimum event length for a USER_VAR_EVENT with checksum. MinUserVarEventLen = uint32(eventHeaderLen+4+1+1) + crc32Len // 29 bytes - // MinQueryEventLen represents the minimum event length for a QueryEvent with checksum + // MinQueryEventLen represents the minimum event length for a QueryEvent with checksum. MinQueryEventLen = uint32(eventHeaderLen+4+4+1+2+2+1+1) + crc32Len // 38 bytes ) @@ -62,9 +62,9 @@ var ( 0x04, 0x1a, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x2a, 0x2a, 0x00, 0x12, 0x34, 0x00, } - // user var name used in dummy USER_VAR_EVENT + // user var name used in dummy USER_VAR_EVENT. dummyUserVarName = []byte("!dummyvar") - // dummy (commented) query in a QueryEvent + // dummy (commented) query in a QueryEvent. dummyQuery = []byte("# dummy query generated by DM, often used to fill a hole in a binlog file") ) @@ -369,7 +369,7 @@ func GenTableMapEvent(header *replication.EventHeader, latestPos uint32, tableID // Post-header postHeader := new(bytes.Buffer) - var tableIDSize = 6 // for binlog V4, this should be 6. + tableIDSize := 6 // for binlog V4, this should be 6. if eventTypeHeaderLen[replication.TABLE_MAP_EVENT-1] == 6 { tableIDSize = 4 } @@ -473,7 +473,7 @@ func GenTableMapEvent(header *replication.EventHeader, latestPos uint32, tableID } var tableMapEvent *replication.BinlogEvent - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { count++ switch count { @@ -540,7 +540,7 @@ func GenRowsEvent(header *replication.EventHeader, latestPos uint32, eventType r postHeader := new(bytes.Buffer) - var tableIDSize = 6 + tableIDSize := 6 if eventTypeHeaderLen[eventType] == 6 { tableIDSize = 4 } @@ -637,7 +637,7 @@ func GenRowsEvent(header *replication.EventHeader, latestPos uint32, eventType r // in order to Decode RowsEvent, we need to set `tableIDSize` and `tables` first, but they are private fields. // so we should parse a FormatDescriptionEvent and a TableMapEvent first. var rowsEvent *replication.BinlogEvent - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { count++ switch count { diff --git a/pkg/binlog/event/event_test.go b/pkg/binlog/event/event_test.go index 0359b207b4..0878e00548 100644 --- a/pkg/binlog/event/event_test.go +++ b/pkg/binlog/event/event_test.go @@ -36,8 +36,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testEventSuite struct { -} +type testEventSuite struct{} func (t *testEventSuite) TestGenEventHeader(c *C) { var ( @@ -192,7 +191,7 @@ func (t *testEventSuite) TestGenPreviousGTIDsEvent(c *C) { _, err = f1.Write(previousGTIDsEv.RawData) c.Assert(err, IsNil) - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { count++ switch count { @@ -310,7 +309,7 @@ func (t *testEventSuite) TestGenGTIDEvent(c *C) { _, err = f.Write(gtidEv.RawData) c.Assert(err, IsNil) - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { count++ switch count { @@ -565,10 +564,14 @@ func (t *testEventSuite) TestGenRowsEvent(c *C) { // more column types rows = make([][]interface{}, 0, 1) - rows = append(rows, []interface{}{int32(1), int8(2), int16(3), int32(4), int64(5), - float32(1.23), float64(4.56), "string with type STRING"}) - columnType = []byte{gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_TINY, gmysql.MYSQL_TYPE_SHORT, gmysql.MYSQL_TYPE_INT24, gmysql.MYSQL_TYPE_LONGLONG, - gmysql.MYSQL_TYPE_FLOAT, gmysql.MYSQL_TYPE_DOUBLE, gmysql.MYSQL_TYPE_STRING} + rows = append(rows, []interface{}{ + int32(1), int8(2), int16(3), int32(4), int64(5), + float32(1.23), float64(4.56), "string with type STRING", + }) + columnType = []byte{ + gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_TINY, gmysql.MYSQL_TYPE_SHORT, gmysql.MYSQL_TYPE_INT24, gmysql.MYSQL_TYPE_LONGLONG, + gmysql.MYSQL_TYPE_FLOAT, gmysql.MYSQL_TYPE_DOUBLE, gmysql.MYSQL_TYPE_STRING, + } rowsEv, err = GenRowsEvent(header, latestPos, eventType, tableID, rowsFlag, rows, columnType, nil) c.Assert(err, IsNil) c.Assert(rowsEv, NotNil) @@ -588,13 +591,15 @@ func (t *testEventSuite) TestGenRowsEvent(c *C) { // NotSupported column type rows = make([][]interface{}, 0, 1) rows = append(rows, []interface{}{int32(1)}) - unsupportedTypes := []byte{gmysql.MYSQL_TYPE_VARCHAR, gmysql.MYSQL_TYPE_VAR_STRING, + unsupportedTypes := []byte{ + gmysql.MYSQL_TYPE_VARCHAR, gmysql.MYSQL_TYPE_VAR_STRING, gmysql.MYSQL_TYPE_NEWDECIMAL, gmysql.MYSQL_TYPE_BIT, gmysql.MYSQL_TYPE_TIMESTAMP, gmysql.MYSQL_TYPE_TIMESTAMP2, gmysql.MYSQL_TYPE_DATETIME, gmysql.MYSQL_TYPE_DATETIME2, gmysql.MYSQL_TYPE_TIME, gmysql.MYSQL_TYPE_TIME2, gmysql.MYSQL_TYPE_YEAR, gmysql.MYSQL_TYPE_ENUM, gmysql.MYSQL_TYPE_SET, - gmysql.MYSQL_TYPE_BLOB, gmysql.MYSQL_TYPE_JSON, gmysql.MYSQL_TYPE_GEOMETRY} + gmysql.MYSQL_TYPE_BLOB, gmysql.MYSQL_TYPE_JSON, gmysql.MYSQL_TYPE_GEOMETRY, + } for i := range unsupportedTypes { columnType = unsupportedTypes[i : i+1] rowsEv, err = GenRowsEvent(header, latestPos, eventType, tableID, rowsFlag, rows, columnType, nil) @@ -756,8 +761,10 @@ func (t *testEventSuite) TestGenDummyEvent(c *C) { // minimum, .., equal dummy query, longer, ... dummyQueryLen := uint32(len(dummyQuery)) - eventSizeList := []uint32{MinQueryEventLen, MinQueryEventLen + 5, - MinQueryEventLen + dummyQueryLen - 1, MinQueryEventLen + dummyQueryLen, MinQueryEventLen + dummyQueryLen + 10} + eventSizeList := []uint32{ + MinQueryEventLen, MinQueryEventLen + 5, + MinQueryEventLen + dummyQueryLen - 1, MinQueryEventLen + dummyQueryLen, MinQueryEventLen + dummyQueryLen + 10, + } for _, eventSize = range eventSizeList { queryEv, err := GenDummyEvent(header, latestPos, eventSize) c.Assert(err, IsNil) diff --git a/pkg/binlog/event/generator_test.go b/pkg/binlog/event/generator_test.go index 26c3791bf2..f46c7199a3 100644 --- a/pkg/binlog/event/generator_test.go +++ b/pkg/binlog/event/generator_test.go @@ -27,8 +27,7 @@ import ( var _ = Suite(&testGeneratorSuite{}) -type testGeneratorSuite struct { -} +type testGeneratorSuite struct{} func (t *testGeneratorSuite) TestGenerateForMySQL(c *C) { var ( @@ -291,7 +290,7 @@ func (t *testGeneratorSuite) testGenerate(c *C, flavor string, serverID uint32, allEventTypes = append(allEventTypes, t.gtidEventType(c, flavor), replication.QUERY_EVENT) // parse the file - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { c.Assert(e.Header.EventType, Equals, allEventTypes[count]) c.Assert(e.RawData, DeepEquals, allEvents[count].RawData) diff --git a/pkg/binlog/event/helper_test.go b/pkg/binlog/event/helper_test.go index 166c4f3333..e35f43adcc 100644 --- a/pkg/binlog/event/helper_test.go +++ b/pkg/binlog/event/helper_test.go @@ -26,8 +26,7 @@ import ( var _ = Suite(&testHelperSuite{}) -type testHelperSuite struct { -} +type testHelperSuite struct{} func (t *testHelperSuite) TestGTIDsFromPreviousGTIDsEvent(c *C) { var ( diff --git a/pkg/binlog/event/sid_mysql_test.go b/pkg/binlog/event/sid_mysql_test.go index 6558f8be33..d6d0a067aa 100644 --- a/pkg/binlog/event/sid_mysql_test.go +++ b/pkg/binlog/event/sid_mysql_test.go @@ -22,8 +22,7 @@ import ( var _ = Suite(&testSIDMySQLSuite{}) -type testSIDMySQLSuite struct { -} +type testSIDMySQLSuite struct{} func (t *testSIDMySQLSuite) TestParseSID(c *C) { s := "9f61c5f9-1eef-11e9-b6cf-0242ac140003" diff --git a/pkg/binlog/event/util.go b/pkg/binlog/event/util.go index 616f826e21..35c00cb26f 100644 --- a/pkg/binlog/event/util.go +++ b/pkg/binlog/event/util.go @@ -69,13 +69,13 @@ func decodeTableMapColumnMeta(data []byte, columnType []byte) ([]uint16, error) for i, t := range columnType { switch t { case gmysql.MYSQL_TYPE_STRING: - var x = uint16(data[pos]) << 8 //real type - x += uint16(data[pos+1]) //pack or field length + x := uint16(data[pos]) << 8 // real type + x += uint16(data[pos+1]) // pack or field length columnMeta[i] = x pos += 2 case gmysql.MYSQL_TYPE_NEWDECIMAL: - var x = uint16(data[pos]) << 8 //precision - x += uint16(data[pos+1]) //decimals + x := uint16(data[pos]) << 8 // precision + x += uint16(data[pos+1]) // decimals columnMeta[i] = x pos += 2 case gmysql.MYSQL_TYPE_VAR_STRING, gmysql.MYSQL_TYPE_VARCHAR, gmysql.MYSQL_TYPE_BIT: @@ -100,12 +100,12 @@ func bitmapByteSize(columnCount int) int { return (columnCount + 7) / 8 } -// nullBytes returns a n-length null bytes slice +// nullBytes returns a n-length null bytes slice. func nullBytes(n int) []byte { return make([]byte, n) } -// fullBytes returns a n-length full bytes slice (all bits are set) +// fullBytes returns a n-length full bytes slice (all bits are set). func fullBytes(n int) []byte { buf := new(bytes.Buffer) for i := 0; i < n; i++ { @@ -144,7 +144,7 @@ func assembleEvent(buf *bytes.Buffer, event replication.Event, decodeWithChecksu } // decode event, some implementations of `Decode` also need checksum - var endIdx = buf.Len() + endIdx := buf.Len() if !decodeWithChecksum { endIdx -= int(crc32Len) } @@ -185,6 +185,7 @@ func combineHeaderPayload(buf *bytes.Buffer, header, postHeader, payload []byte) // encodeColumnValue encodes value to bytes // ref: https://github.com/siddontang/go-mysql/blob/88e9cd7f6643b246b4dcc0e3206e9a169dd0ac96/replication/row_event.go#L368 // NOTE: we do not generate meaningful `meta` yet. +// nolint:unparam func encodeColumnValue(v interface{}, tp byte, meta uint16) ([]byte, error) { var ( buf = new(bytes.Buffer) @@ -289,10 +290,10 @@ const ( QTableMapForUpdateCode QMasterDataWrittenCode QInvokers - QUpdatedDbNames + QUpdatedDBNames QMicroseconds - QCommitTs - QCommitTs2 + QCommitTS + QCommitTS2 QExplicitDefaultsForTimestamp QDdlLoggedWithXid QDefaultCollationForUtf8mb4 @@ -301,33 +302,31 @@ const ( QHrnow = 128 ) -var ( - // https://dev.mysql.com/doc/internals/en/query-event.html - statusVarsFixedLength = map[byte]int{ - QFlags2Code: 4, - QSqlModeCode: 8, - QAutoIncrement: 2 + 2, - QCharsetCode: 2 + 2 + 2, - QLcTimeNamesCode: 2, - QCharsetDatabaseCode: 2, - QTableMapForUpdateCode: 8, - QMasterDataWrittenCode: 4, - QMicroseconds: 3, - QCommitTs: 0, // unused now - QCommitTs2: 0, // unused now - // below variables could be find in - // https://github.com/mysql/mysql-server/blob/7d10c82196c8e45554f27c00681474a9fb86d137/libbinlogevents/src/statement_events.cpp#L312 - QExplicitDefaultsForTimestamp: 1, - QDdlLoggedWithXid: 8, - QDefaultCollationForUtf8mb4: 2, - QSqlRequirePrimaryKey: 1, - QDefaultTableEncryption: 1, - // https://github.com/MariaDB/server/blob/94b45787045677c106a25ebb5aaf1273040b2ff6/sql/log_event.cc#L1619 - QHrnow: 3, - } -) +// https://dev.mysql.com/doc/internals/en/query-event.html +var statusVarsFixedLength = map[byte]int{ + QFlags2Code: 4, + QSqlModeCode: 8, + QAutoIncrement: 2 + 2, + QCharsetCode: 2 + 2 + 2, + QLcTimeNamesCode: 2, + QCharsetDatabaseCode: 2, + QTableMapForUpdateCode: 8, + QMasterDataWrittenCode: 4, + QMicroseconds: 3, + QCommitTS: 0, // unused now + QCommitTS2: 0, // unused now + // below variables could be find in + // https://github.com/mysql/mysql-server/blob/7d10c82196c8e45554f27c00681474a9fb86d137/libbinlogevents/src/statement_events.cpp#L312 + QExplicitDefaultsForTimestamp: 1, + QDdlLoggedWithXid: 8, + QDefaultCollationForUtf8mb4: 2, + QSqlRequirePrimaryKey: 1, + QDefaultTableEncryption: 1, + // https://github.com/MariaDB/server/blob/94b45787045677c106a25ebb5aaf1273040b2ff6/sql/log_event.cc#L1619 + QHrnow: 3, +} -// getSQLMode gets SQL mode from binlog statusVars, still could return a reasonable value if found error +// getSQLMode gets SQL mode from binlog statusVars, still could return a reasonable value if found error. func getSQLMode(statusVars []byte) (mysql.SQLMode, error) { vars, err := statusVarsToKV(statusVars) b, ok := vars[QSqlModeCode] @@ -347,7 +346,7 @@ func getSQLMode(statusVars []byte) (mysql.SQLMode, error) { return mysql.SQLMode(v), err } -// GetParserForStatusVars gets a parser for binlog which is suitable for its sql_mode in statusVars +// GetParserForStatusVars gets a parser for binlog which is suitable for its sql_mode in statusVars. func GetParserForStatusVars(statusVars []byte) (*parser.Parser, error) { parser2 := parser.New() mode, err := getSQLMode(statusVars) @@ -356,13 +355,11 @@ func GetParserForStatusVars(statusVars []byte) (*parser.Parser, error) { } // if returned error is `io.EOF`, it means UnexpectedEOF because we handled expected `io.EOF` as success -// returned map should not be nil for other usage +// returned map should not be nil for other usage. func statusVarsToKV(statusVars []byte) (map[byte][]byte, error) { r := bytes.NewReader(statusVars) vars := make(map[byte][]byte) - var ( - value []byte - ) + var value []byte // NOTE: this closure modifies variable `value` appendLengthThenCharsToValue := func() error { @@ -427,6 +424,7 @@ func statusVarsToKV(statusVars []byte) (map[byte][]byte, error) { if err2 != nil { return generateError(err) } + // nolint:makezero value = append(value, b) // 1-byte length + chars of the timezone/catalog case QTimeZoneCode, QCatalogNzCode: @@ -442,11 +440,12 @@ func statusVarsToKV(statusVars []byte) (map[byte][]byte, error) { return generateError(err) } // 1-byte count + \0 terminated string - case QUpdatedDbNames: + case QUpdatedDBNames: count, err := r.ReadByte() if err != nil { return generateError(err) } + // nolint:makezero value = append(value, count) // if count is 254 (OVER_MAX_DBS_IN_EVENT_MTS), there's no following DB names // https://github.com/mysql/mysql-server/blob/ee4455a33b10f1b1886044322e4893f587b319ed/libbinlogevents/include/binlog_event.h#L107 @@ -467,6 +466,7 @@ func statusVarsToKV(statusVars []byte) (map[byte][]byte, error) { } b = byte(1) // reset to any non-zero value } + // nolint:makezero value = append(value, buf...) default: return generateError(errors.New("unrecognized key")) diff --git a/pkg/binlog/event/util_test.go b/pkg/binlog/event/util_test.go index 1a81806e00..e3df4b3137 100644 --- a/pkg/binlog/event/util_test.go +++ b/pkg/binlog/event/util_test.go @@ -26,8 +26,7 @@ import ( var _ = Suite(&testUtilSuite{}) -type testUtilSuite struct { -} +type testUtilSuite struct{} type testCase struct { input []byte diff --git a/pkg/binlog/filename_test.go b/pkg/binlog/filename_test.go index 4234e864a3..747d9a5b13 100644 --- a/pkg/binlog/filename_test.go +++ b/pkg/binlog/filename_test.go @@ -19,8 +19,7 @@ import ( var _ = Suite(&testFilenameSuite{}) -type testFilenameSuite struct { -} +type testFilenameSuite struct{} func (t *testFilenameSuite) TestFilenameCmp(c *C) { f1 := Filename{ diff --git a/pkg/binlog/position.go b/pkg/binlog/position.go index 6f302e1a59..5a665d2aff 100644 --- a/pkg/binlog/position.go +++ b/pkg/binlog/position.go @@ -18,7 +18,6 @@ import ( "strconv" "strings" - "github.com/siddontang/go-mysql/mysql" gmysql "github.com/siddontang/go-mysql/mysql" "go.uber.org/zap" @@ -34,18 +33,16 @@ const ( // conversion: originalPos.NamePrefix + posUUIDSuffixSeparator + UUIDSuffix + binlogFilenameSep + originalPos.NameSuffix => convertedPos.Name // UUIDSuffix is the suffix of sub relay directory name, and when new sub directory created, UUIDSuffix is incremented // eg. mysql-bin.000003 in c6ae5afe-c7a3-11e8-a19d-0242ac130006.000002 => mysql-bin|000002.000003 - // where `000002` in `c6ae5afe-c7a3-11e8-a19d-0242ac130006.000002` is the UUIDSuffix + // where `000002` in `c6ae5afe-c7a3-11e8-a19d-0242ac130006.000002` is the UUIDSuffix. posUUIDSuffixSeparator = "|" - // MinUUIDSuffix is same as relay.MinUUIDSuffix + // MinUUIDSuffix is same as relay.MinUUIDSuffix. MinUUIDSuffix = 1 ) -var ( - // MinPosition is the min binlog position - MinPosition = gmysql.Position{Pos: 4} -) +// MinPosition is the min binlog position. +var MinPosition = gmysql.Position{Pos: 4} -// PositionFromStr constructs a mysql.Position from a string representation like `mysql-bin.000001:2345` +// PositionFromStr constructs a mysql.Position from a string representation like `mysql-bin.000001:2345`. func PositionFromStr(s string) (gmysql.Position, error) { parsed := strings.Split(s, ":") if len(parsed) != 2 { @@ -69,7 +66,7 @@ func trimBrackets(s string) string { return s } -// PositionFromPosStr constructs a mysql.Position from a string representation like `(mysql-bin.000001, 2345)` +// PositionFromPosStr constructs a mysql.Position from a string representation like `(mysql-bin.000001, 2345)`. func PositionFromPosStr(str string) (gmysql.Position, error) { s := trimBrackets(str) parsed := strings.Split(s, ", ") @@ -112,7 +109,7 @@ func RealMySQLPos(pos gmysql.Position) (gmysql.Position, error) { return pos, nil } -// ExtractSuffix extracts uuidSuffix from input name +// ExtractSuffix extracts uuidSuffix from input name. func ExtractSuffix(name string) (int, error) { if len(name) == 0 { return MinUUIDSuffix, nil @@ -130,7 +127,8 @@ func ExtractSuffix(name string) (int, error) { return MinUUIDSuffix, nil } -// ExtractPos extracts (uuidWithSuffix, uuidSuffix, originalPos) from input pos (originalPos or convertedPos) +// ExtractPos extracts (uuidWithSuffix, uuidSuffix, originalPos) from input pos (originalPos or convertedPos). +// nolint:nakedret func ExtractPos(pos gmysql.Position, uuids []string) (uuidWithSuffix string, uuidSuffix string, realPos gmysql.Position, err error) { if len(uuids) == 0 { err = terror.ErrBinlogExtractPosition.New("empty UUIDs not valid") @@ -189,7 +187,7 @@ func verifyUUIDSuffix(suffix string) bool { } // AdjustPosition adjusts the filename with uuid suffix in mysql position -// for example: mysql-bin|000001.000002 -> mysql-bin.000002 +// for example: mysql-bin|000001.000002 -> mysql-bin.000002. func AdjustPosition(pos gmysql.Position) gmysql.Position { realPos, err := RealMySQLPos(pos) if err != nil { @@ -200,7 +198,7 @@ func AdjustPosition(pos gmysql.Position) gmysql.Position { return realPos } -// VerifyBinlogPos verify binlog pos string +// VerifyBinlogPos verify binlog pos string. func VerifyBinlogPos(pos string) (*gmysql.Position, error) { binlogPosStr := utils.TrimQuoteMark(pos) pos2, err := PositionFromStr(binlogPosStr) @@ -227,7 +225,7 @@ func ComparePosition(pos1, pos2 gmysql.Position) int { } // Location is used for save binlog's position and gtid -// TODO: encapsulate all attributes in Location +// TODO: encapsulate all attributes in Location. type Location struct { Position gmysql.Position @@ -236,7 +234,7 @@ type Location struct { Suffix int // use for replace event } -// NewLocation returns a new Location +// NewLocation returns a new Location. func NewLocation(flavor string) Location { return Location{ Position: MinPosition, @@ -244,7 +242,7 @@ func NewLocation(flavor string) Location { } } -// InitLocation init a new Location +// InitLocation init a new Location. func InitLocation(pos gmysql.Position, gset gtid.Set) Location { return Location{ Position: pos, @@ -259,7 +257,7 @@ func (l Location) String() string { return fmt.Sprintf("position: %v, gtid-set: %s, suffix: %d", l.Position, l.GTIDSetStr(), l.Suffix) } -// GTIDSetStr returns gtid set's string +// GTIDSetStr returns gtid set's string. func (l Location) GTIDSetStr() string { gsetStr := "" if l.gtidSet != nil { @@ -269,7 +267,7 @@ func (l Location) GTIDSetStr() string { return gsetStr } -// Clone clones a same Location +// Clone clones a same Location. func (l Location) Clone() Location { return l.CloneWithFlavor("") } @@ -322,17 +320,18 @@ func CompareLocation(location1, location2 Location, cmpGTID bool) int { // 1, true if gSet1 is bigger than gSet2 // 0, true if gSet1 is equal to gSet2 // -1, true if gSet1 is less than gSet2 -// but if can't compare gSet1 and gSet2, will returns 0, false +// but if can't compare gSet1 and gSet2, will returns 0, false. func CompareGTID(gSet1, gSet2 gtid.Set) (int, bool) { gSetIsEmpty1 := gSet1 == nil || len(gSet1.String()) == 0 gSetIsEmpty2 := gSet2 == nil || len(gSet2.String()) == 0 - if gSetIsEmpty1 && gSetIsEmpty2 { + switch { + case gSetIsEmpty1 && gSetIsEmpty2: // both gSet1 and gSet2 is nil return 0, true - } else if gSetIsEmpty1 { + case gSetIsEmpty1: return -1, true - } else if gSetIsEmpty2 { + case gSetIsEmpty2: return 1, true } @@ -354,26 +353,27 @@ func CompareGTID(gSet1, gSet2 gtid.Set) (int, bool) { } func compareIndex(lhs, rhs int) int { - if lhs < rhs { + switch { + case lhs < rhs: return -1 - } else if lhs > rhs { + case lhs > rhs: return 1 - } else { + default: return 0 } } -// ResetSuffix set suffix to 0 +// ResetSuffix set suffix to 0. func (l *Location) ResetSuffix() { l.Suffix = 0 } // SetGTID set new gtid for location -// Use this func instead of GITSet.Set to avoid change other location -func (l *Location) SetGTID(gset mysql.GTIDSet) error { - flavor := mysql.MySQLFlavor +// Use this func instead of GITSet.Set to avoid change other location. +func (l *Location) SetGTID(gset gmysql.GTIDSet) error { + flavor := gmysql.MySQLFlavor if _, ok := l.gtidSet.(*gtid.MariadbGTIDSet); ok { - flavor = mysql.MariaDBFlavor + flavor = gmysql.MariaDBFlavor } newGTID := gtid.MinGTIDSet(flavor) @@ -385,7 +385,7 @@ func (l *Location) SetGTID(gset mysql.GTIDSet) error { return nil } -// GetGTID return gtidSet of Location +// GetGTID return gtidSet of Location. func (l *Location) GetGTID() gtid.Set { return l.gtidSet } diff --git a/pkg/binlog/position_test.go b/pkg/binlog/position_test.go index 24d8526075..12ad017498 100644 --- a/pkg/binlog/position_test.go +++ b/pkg/binlog/position_test.go @@ -28,8 +28,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testPositionSuite struct { -} +type testPositionSuite struct{} func (t *testPositionSuite) TestPositionFromStr(c *C) { emptyPos := gmysql.Position{} @@ -774,14 +773,16 @@ func (t *testPositionSuite) TestExtractSuffix(c *C) { { "", MinUUIDSuffix, - }, { + }, + { "mysql-bin.00005", MinUUIDSuffix, }, { "mysql-bin|000001.000001", 1, - }, { + }, + { "mysql-bin|000005.000004", 5, }, diff --git a/pkg/binlog/reader/file_test.go b/pkg/binlog/reader/file_test.go index 712a566369..ed9820ca2c 100644 --- a/pkg/binlog/reader/file_test.go +++ b/pkg/binlog/reader/file_test.go @@ -32,12 +32,9 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -var ( - _ = Suite(&testFileReaderSuite{}) -) +var _ = Suite(&testFileReaderSuite{}) -type testFileReaderSuite struct { -} +type testFileReaderSuite struct{} func (t *testFileReaderSuite) TestInterfaceMethods(c *C) { var ( diff --git a/pkg/binlog/reader/mock_test.go b/pkg/binlog/reader/mock_test.go index 8a4e8387ac..c4e2befe71 100644 --- a/pkg/binlog/reader/mock_test.go +++ b/pkg/binlog/reader/mock_test.go @@ -23,12 +23,9 @@ import ( "github.com/siddontang/go-mysql/replication" ) -var ( - _ = Suite(&testMockReaderSuite{}) -) +var _ = Suite(&testMockReaderSuite{}) -type testMockReaderSuite struct { -} +type testMockReaderSuite struct{} type testMockCase struct { ev *replication.BinlogEvent diff --git a/pkg/binlog/reader/util.go b/pkg/binlog/reader/util.go index 01aaee33db..8c1166c0a5 100644 --- a/pkg/binlog/reader/util.go +++ b/pkg/binlog/reader/util.go @@ -142,7 +142,7 @@ func GetGTIDsForPos(ctx context.Context, r Reader, endPos gmysql.Position) (gtid } // GetPreviousGTIDFromGTIDSet tries to get previous GTID sets from Previous_GTID_EVENT GTID for the specified GITD Set. -// events should be [fake_rotate_event,format_description_event,previous_gtids_event/mariadb_gtid_list_event] +// events should be [fake_rotate_event,format_description_event,previous_gtids_event/mariadb_gtid_list_event]. func GetPreviousGTIDFromGTIDSet(ctx context.Context, r Reader, gset gtid.Set) (gtid.Set, error) { err := r.StartSyncByGTID(gset) if err != nil { diff --git a/pkg/binlog/writer/file.go b/pkg/binlog/writer/file.go index 7236ca2482..963baed660 100644 --- a/pkg/binlog/writer/file.go +++ b/pkg/binlog/writer/file.go @@ -79,7 +79,7 @@ func (w *FileWriter) Start() error { return terror.ErrBinlogWriterNotStateNew.Generate(w.stage, common.StageNew) } - f, err := os.OpenFile(w.cfg.Filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) + f, err := os.OpenFile(w.cfg.Filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o644) if err != nil { return terror.ErrBinlogWriterOpenFile.Delegate(err) } diff --git a/pkg/binlog/writer/file_test.go b/pkg/binlog/writer/file_test.go index 98e4a2d213..c5040e38ec 100644 --- a/pkg/binlog/writer/file_test.go +++ b/pkg/binlog/writer/file_test.go @@ -31,12 +31,9 @@ func TestSuite(t *testing.T) { TestingT(t) } -var ( - _ = Suite(&testFileWriterSuite{}) -) +var _ = Suite(&testFileWriterSuite{}) -type testFileWriterSuite struct { -} +type testFileWriterSuite struct{} func (t *testFileWriterSuite) TestWrite(c *C) { dir := c.MkDir() diff --git a/pkg/conn/baseconn.go b/pkg/conn/baseconn.go index 1766085e4e..2d1c093b7d 100644 --- a/pkg/conn/baseconn.go +++ b/pkg/conn/baseconn.go @@ -67,14 +67,14 @@ import ( // it ignore already exists error and it should be removed after use, one unit has one connection // // each connection should have ability to retry on some common errors (e.g. tmysql.ErrTiKVServerTimeout) or maybe some specify errors in the future -// and each connection also should have ability to reset itself during some specify connection error (e.g. driver.ErrBadConn) +// and each connection also should have ability to reset itself during some specify connection error (e.g. driver.ErrBadConn). type BaseConn struct { DBConn *sql.Conn RetryStrategy retry.Strategy } -// NewBaseConn builds BaseConn to connect real DB +// NewBaseConn builds BaseConn to connect real DB. func NewBaseConn(conn *sql.Conn, strategy retry.Strategy) *BaseConn { if strategy == nil { strategy = &retry.FiniteRetryStrategy{} @@ -82,7 +82,7 @@ func NewBaseConn(conn *sql.Conn, strategy retry.Strategy) *BaseConn { return &BaseConn{conn, strategy} } -// SetRetryStrategy set retry strategy for baseConn +// SetRetryStrategy set retry strategy for baseConn. func (conn *BaseConn) SetRetryStrategy(strategy retry.Strategy) error { if conn == nil { return terror.ErrDBUnExpect.Generate("database connection not valid") @@ -91,7 +91,7 @@ func (conn *BaseConn) SetRetryStrategy(strategy retry.Strategy) error { return nil } -// QuerySQL defines query statement, and connect to real DB +// QuerySQL defines query statement, and connect to real DB. func (conn *BaseConn) QuerySQL(tctx *tcontext.Context, query string, args ...interface{}) (*sql.Rows, error) { if conn == nil || conn.DBConn == nil { return nil, terror.ErrDBUnExpect.Generate("database connection not valid") @@ -101,7 +101,6 @@ func (conn *BaseConn) QuerySQL(tctx *tcontext.Context, query string, args ...int zap.String("argument", utils.TruncateInterface(args, -1))) rows, err := conn.DBConn.QueryContext(tctx.Context(), query, args...) - if err != nil { tctx.L().ErrorFilterContextCanceled("query statement failed", zap.String("query", utils.TruncateString(query, -1)), @@ -115,7 +114,7 @@ func (conn *BaseConn) QuerySQL(tctx *tcontext.Context, query string, args ...int // ExecuteSQLWithIgnoreError executes sql on real DB, and will ignore some error and continue execute the next query. // return // 1. failed: (the index of sqls executed error, error) -// 2. succeed: (len(sqls), nil) +// 2. succeed: (len(sqls), nil). func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *metricsproxy.HistogramVecProxy, task string, ignoreErr func(error) bool, queries []string, args ...[]interface{}) (int, error) { // inject an error to trigger retry, this should be placed before the real execution of the SQL statement. failpoint.Inject("retryableError", func(val failpoint.Value) { @@ -130,7 +129,8 @@ func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *me tctx.L().Info("", zap.String("failpoint", "retryableError"), zap.String("mark", mark)) failpoint.Return(0, &mysql.MySQLError{ Number: gmysql.ER_LOCK_DEADLOCK, - Message: fmt.Sprintf("failpoint inject retryable error for %s", mark)}) + Message: fmt.Sprintf("failpoint inject retryable error for %s", mark), + }) } } }) @@ -144,7 +144,6 @@ func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *me startTime := time.Now() txn, err := conn.DBConn.BeginTx(tctx.Context(), nil) - if err != nil { return 0, terror.ErrDBExecuteFailed.Delegate(err, "begin") } @@ -214,12 +213,12 @@ func (conn *BaseConn) ExecuteSQLWithIgnoreError(tctx *tcontext.Context, hVec *me // ExecuteSQL executes sql on real DB, // return // 1. failed: (the index of sqls executed error, error) -// 2. succeed: (len(sqls), nil) +// 2. succeed: (len(sqls), nil). func (conn *BaseConn) ExecuteSQL(tctx *tcontext.Context, hVec *metricsproxy.HistogramVecProxy, task string, queries []string, args ...[]interface{}) (int, error) { return conn.ExecuteSQLWithIgnoreError(tctx, hVec, task, nil, queries, args...) } -// ApplyRetryStrategy apply specify strategy for BaseConn +// ApplyRetryStrategy apply specify strategy for BaseConn. func (conn *BaseConn) ApplyRetryStrategy(tctx *tcontext.Context, params retry.Params, operateFn func(*tcontext.Context) (interface{}, error)) (interface{}, int, error) { return conn.RetryStrategy.Apply(tctx, params, operateFn) diff --git a/pkg/conn/baseconn_test.go b/pkg/conn/baseconn_test.go index 4f22048e0c..c3d272b60c 100644 --- a/pkg/conn/baseconn_test.go +++ b/pkg/conn/baseconn_test.go @@ -34,19 +34,16 @@ func TestSuite(t *testing.T) { var _ = Suite(&testBaseConnSuite{}) -type testBaseConnSuite struct { -} +type testBaseConnSuite struct{} -var ( - testStmtHistogram = metricsproxy.NewHistogramVec( - prometheus.HistogramOpts{ - Namespace: "dm", - Subsystem: "conn", - Name: "stmt_duration_time", - Help: "Bucketed histogram of every statement query time (s).", - Buckets: prometheus.ExponentialBuckets(0.0005, 2, 18), - }, []string{"type", "task"}) -) +var testStmtHistogram = metricsproxy.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: "dm", + Subsystem: "conn", + Name: "stmt_duration_time", + Help: "Bucketed histogram of every statement query time (s).", + Buckets: prometheus.ExponentialBuckets(0.0005, 2, 18), + }, []string{"type", "task"}) func (t *testBaseConnSuite) TestBaseConn(c *C) { baseConn := NewBaseConn(nil, nil) @@ -55,6 +52,7 @@ func (t *testBaseConnSuite) TestBaseConn(c *C) { err := baseConn.SetRetryStrategy(nil) c.Assert(err, IsNil) + // nolint:sqlclosecheck _, err = baseConn.QuerySQL(tctx, "select 1") c.Assert(terror.ErrDBUnExpect.Equal(err), IsTrue) @@ -72,6 +70,7 @@ func (t *testBaseConnSuite) TestBaseConn(c *C) { c.Assert(err, IsNil) mock.ExpectQuery("select 1").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1)) + // nolint:sqlclosecheck rows, err := baseConn.QuerySQL(tctx, "select 1") c.Assert(err, IsNil) ids := make([]int, 0, 1) @@ -85,6 +84,7 @@ func (t *testBaseConnSuite) TestBaseConn(c *C) { c.Assert(ids[0], Equals, 1) mock.ExpectQuery("select 1").WillReturnError(errors.New("invalid connection")) + // nolint:sqlclosecheck _, err = baseConn.QuerySQL(tctx, "select 1") c.Assert(terror.ErrDBQueryFailed.Equal(err), IsTrue) diff --git a/pkg/conn/basedb.go b/pkg/conn/basedb.go index a546a2a785..07b2ddad2f 100644 --- a/pkg/conn/basedb.go +++ b/pkg/conn/basedb.go @@ -37,26 +37,25 @@ import ( var customID int64 -// DBProvider providers BaseDB instance +// DBProvider providers BaseDB instance. type DBProvider interface { Apply(config config.DBConfig) (*BaseDB, error) } -// DefaultDBProviderImpl is default DBProvider implement -type DefaultDBProviderImpl struct { -} +// DefaultDBProviderImpl is default DBProvider implement. +type DefaultDBProviderImpl struct{} -// DefaultDBProvider is global instance of DBProvider +// DefaultDBProvider is global instance of DBProvider. var DefaultDBProvider DBProvider func init() { DefaultDBProvider = &DefaultDBProviderImpl{} } -// mockDB is used in unit test +// mockDB is used in unit test. var mockDB sqlmock.Sqlmock -// Apply will build BaseDB with DBConfig +// Apply will build BaseDB with DBConfig. func (d *DefaultDBProviderImpl) Apply(config config.DBConfig) (*BaseDB, error) { // maxAllowedPacket=0 can be used to automatically fetch the max_allowed_packet variable from server on every connection. // https://github.com/go-sql-driver/mysql#maxallowedpacket @@ -129,7 +128,7 @@ func (d *DefaultDBProviderImpl) Apply(config config.DBConfig) (*BaseDB, error) { return NewBaseDB(db, doFuncInClose), nil } -// BaseDB wraps *sql.DB, control the BaseConn +// BaseDB wraps *sql.DB, control the BaseConn. type BaseDB struct { DB *sql.DB @@ -143,13 +142,13 @@ type BaseDB struct { doFuncInClose func() } -// NewBaseDB returns *BaseDB object +// NewBaseDB returns *BaseDB object. func NewBaseDB(db *sql.DB, doFuncInClose func()) *BaseDB { conns := make(map[*BaseConn]struct{}) return &BaseDB{DB: db, conns: conns, Retry: &retry.FiniteRetryStrategy{}, doFuncInClose: doFuncInClose} } -// GetBaseConn retrieves *BaseConn which has own retryStrategy +// GetBaseConn retrieves *BaseConn which has own retryStrategy. func (d *BaseDB) GetBaseConn(ctx context.Context) (*BaseConn, error) { conn, err := d.DB.Conn(ctx) if err != nil { @@ -166,7 +165,7 @@ func (d *BaseDB) GetBaseConn(ctx context.Context) (*BaseConn, error) { return baseConn, nil } -// CloseBaseConn release BaseConn resource from BaseDB, and close BaseConn +// CloseBaseConn release BaseConn resource from BaseDB, and close BaseConn. func (d *BaseDB) CloseBaseConn(conn *BaseConn) error { d.mu.Lock() defer d.mu.Unlock() @@ -174,7 +173,7 @@ func (d *BaseDB) CloseBaseConn(conn *BaseConn) error { return conn.close() } -// Close release *BaseDB resource +// Close release *BaseDB resource. func (d *BaseDB) Close() error { if d == nil || d.DB == nil { return nil diff --git a/pkg/conn/basedb_test.go b/pkg/conn/basedb_test.go index 56228422d5..4e26213275 100644 --- a/pkg/conn/basedb_test.go +++ b/pkg/conn/basedb_test.go @@ -25,8 +25,7 @@ import ( var _ = Suite(&testBaseDBSuite{}) -type testBaseDBSuite struct { -} +type testBaseDBSuite struct{} func (t *testBaseDBSuite) TestGetBaseConn(c *C) { db, mock, err := sqlmock.New() @@ -41,6 +40,7 @@ func (t *testBaseDBSuite) TestGetBaseConn(c *C) { c.Assert(err, IsNil) mock.ExpectQuery("select 1").WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow("1")) + // nolint:sqlclosecheck rows, err := dbConn.QuerySQL(tctx, "select 1") c.Assert(err, IsNil) ids := make([]int, 0, 1) diff --git a/pkg/context/context.go b/pkg/context/context.go index ab3c178a70..ab9603d9d4 100644 --- a/pkg/context/context.go +++ b/pkg/context/context.go @@ -22,13 +22,13 @@ import ( // Context is used to in dm to record some context field like // * go context -// * logger +// * logger. type Context struct { Ctx context.Context Logger log.Logger } -// Background return a nop context +// Background return a nop context. func Background() *Context { return &Context{ Ctx: context.Background(), @@ -36,7 +36,7 @@ func Background() *Context { } } -// NewContext return a new Context +// NewContext return a new Context. func NewContext(ctx context.Context, logger log.Logger) *Context { return &Context{ Ctx: ctx, @@ -44,7 +44,7 @@ func NewContext(ctx context.Context, logger log.Logger) *Context { } } -// WithContext set go context +// WithContext set go context. func (c *Context) WithContext(ctx context.Context) *Context { return &Context{ Ctx: ctx, @@ -61,12 +61,12 @@ func (c *Context) WithTimeout(timeout time.Duration) (*Context, context.CancelFu }, cancel } -// Context returns real context +// Context returns real context. func (c *Context) Context() context.Context { return c.Ctx } -// WithLogger set logger +// WithLogger set logger. func (c *Context) WithLogger(logger log.Logger) *Context { return &Context{ Ctx: c.Ctx, @@ -74,7 +74,7 @@ func (c *Context) WithLogger(logger log.Logger) *Context { } } -// L returns real logger +// L returns real logger. func (c *Context) L() log.Logger { return c.Logger } diff --git a/pkg/cputil/table.go b/pkg/cputil/table.go index a75bc71d7a..d8eb4385e8 100644 --- a/pkg/cputil/table.go +++ b/pkg/cputil/table.go @@ -13,22 +13,22 @@ package cputil -// LoaderCheckpoint returns loader's checkpoint table name +// LoaderCheckpoint returns loader's checkpoint table name. func LoaderCheckpoint(task string) string { return task + "_loader_checkpoint" } -// SyncerCheckpoint returns syncer's checkpoint table name +// SyncerCheckpoint returns syncer's checkpoint table name. func SyncerCheckpoint(task string) string { return task + "_syncer_checkpoint" } -// SyncerShardMeta returns syncer's sharding meta table name for pessimistic +// SyncerShardMeta returns syncer's sharding meta table name for pessimistic. func SyncerShardMeta(task string) string { return task + "_syncer_sharding_meta" } -// SyncerOnlineDDL returns syncer's onlineddl checkpoint table name +// SyncerOnlineDDL returns syncer's onlineddl checkpoint table name. func SyncerOnlineDDL(task string) string { return task + "_onlineddl" } diff --git a/pkg/dumpling/utils.go b/pkg/dumpling/utils.go index 2a3a168e07..31ae109896 100644 --- a/pkg/dumpling/utils.go +++ b/pkg/dumpling/utils.go @@ -177,6 +177,7 @@ func readFollowingGTIDs(br *bufio.Reader, flavor string) (string, error) { // try parse to verify it _, err = gtid.ParserGTID(flavor, line[:end]) if err != nil { + // nolint:nilerr return following.String(), nil // return the previous, not including this non-GTID line. } diff --git a/pkg/dumpling/utils_test.go b/pkg/dumpling/utils_test.go index ff9f541a77..998c0bf69b 100644 --- a/pkg/dumpling/utils_test.go +++ b/pkg/dumpling/utils_test.go @@ -31,8 +31,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testSuite struct { -} +type testSuite struct{} func (t *testSuite) TestParseMetaData(c *C) { f, err := ioutil.TempFile("", "metadata") @@ -233,7 +232,7 @@ Finished dump at: 2020-09-30 12:16:49 } for _, tc := range testCases { - err2 := ioutil.WriteFile(f.Name(), []byte(tc.source), 0644) + err2 := ioutil.WriteFile(f.Name(), []byte(tc.source), 0o644) c.Assert(err2, IsNil) loc, loc2, err2 := ParseMetaData(f.Name(), "mysql") c.Assert(err2, IsNil) @@ -252,7 +251,7 @@ Finished dump at: 2020-09-30 12:16:49 noBinlogLoc := `Started dump at: 2020-12-02 17:13:56 Finished dump at: 2020-12-02 17:13:56 ` - err = ioutil.WriteFile(f.Name(), []byte(noBinlogLoc), 0644) + err = ioutil.WriteFile(f.Name(), []byte(noBinlogLoc), 0o644) c.Assert(err, IsNil) _, _, err = ParseMetaData(f.Name(), "mysql") c.Assert(terror.ErrMetadataNoBinlogLoc.Equal(err), IsTrue) diff --git a/pkg/election/election.go b/pkg/election/election.go index ff530aca98..a3be717be6 100644 --- a/pkg/election/election.go +++ b/pkg/election/election.go @@ -41,15 +41,15 @@ const ( // newSessionRetryInterval is the interval time when retrying to create a new session. newSessionRetryInterval = 200 * time.Millisecond - // IsLeader means current compaigner become leader + // IsLeader means current compaigner become leader. IsLeader = "isLeader" - // RetireFromLeader means current compaigner is old leader, and retired + // RetireFromLeader means current compaigner is old leader, and retired. RetireFromLeader = "retireFromLeader" - // IsNotLeader means current compaigner is not old leader and current leader + // IsNotLeader means current compaigner is not old leader and current leader. IsNotLeader = "isNotLeader" ) -// CampaignerInfo is the campaigner's information +// CampaignerInfo is the campaigner's information. type CampaignerInfo struct { ID string `json:"id"` // addr is the campaigner's advertise address @@ -206,7 +206,7 @@ func (e *Election) campaignLoop(ctx context.Context, session *concurrency.Sessio } } failpoint.Inject("mockCampaignLoopExitedAbnormally", func(_ failpoint.Value) { - closeSession = func(se *concurrency.Session) { + closeSession = func(_ *concurrency.Session) { e.l.Info("skip closeSession", zap.String("failpoint", "mockCampaignLoopExitedAbnormally")) } }) @@ -405,7 +405,7 @@ func (e *Election) watchLeader(ctx context.Context, session *concurrency.Session } } -// EvictLeader set evictLeader to true, and this member can't be leader +// EvictLeader set evictLeader to true, and this member can't be leader. func (e *Election) EvictLeader() { if !e.evictLeader.CompareAndSwap(0, 1) { return @@ -414,7 +414,7 @@ func (e *Election) EvictLeader() { e.Resign() } -// Resign resign the leader +// Resign resign the leader. func (e *Election) Resign() { // cancel campaign or current member is leader and then resign e.campaignMu.Lock() @@ -429,7 +429,7 @@ func (e *Election) Resign() { e.campaignMu.Unlock() } -// CancelEvictLeader set evictLeader to false, and this member can campaign leader again +// CancelEvictLeader set evictLeader to false, and this member can campaign leader again. func (e *Election) CancelEvictLeader() { if !e.evictLeader.CompareAndSwap(1, 0) { return @@ -476,7 +476,7 @@ forLoop: } // ClearSessionIfNeeded will clear session when deleted master quited abnormally -// returns (triggered deleting session, error) +// returns (triggered deleting session, error). func (e *Election) ClearSessionIfNeeded(ctx context.Context, id string) (bool, error) { resp, err := e.cli.Get(ctx, e.key, clientv3.WithPrefix()) if err != nil { diff --git a/pkg/election/election_test.go b/pkg/election/election_test.go index 29061aaf8c..c979444b2a 100644 --- a/pkg/election/election_test.go +++ b/pkg/election/election_test.go @@ -285,7 +285,6 @@ func (t *testElectionSuite) TestElectionAlways1(c *C) { c.Assert(leaderID, Equals, e1.ID()) c.Assert(leaderAddr, Equals, addr1) c.Assert(e2.IsLeader(), IsFalse) - } func (t *testElectionSuite) TestElectionEvictLeader(c *C) { diff --git a/pkg/encrypt/encrypt.go b/pkg/encrypt/encrypt.go index 0cc2bba109..54a2ea6990 100644 --- a/pkg/encrypt/encrypt.go +++ b/pkg/encrypt/encrypt.go @@ -28,7 +28,7 @@ var ( ivSep = []byte("@") // ciphertext format: iv + ivSep + encrypted-plaintext ) -// SetSecretKey sets the secret key which used to encrypt +// SetSecretKey sets the secret key which used to encrypt. func SetSecretKey(key []byte) error { switch len(key) { case 16, 24, 32: @@ -40,7 +40,7 @@ func SetSecretKey(key []byte) error { return nil } -// Encrypt encrypts plaintext to ciphertext +// Encrypt encrypts plaintext to ciphertext. func Encrypt(plaintext []byte) ([]byte, error) { block, err := aes.NewCipher(secretKey) if err != nil { @@ -63,7 +63,7 @@ func Encrypt(plaintext []byte) ([]byte, error) { return ciphertext, nil } -// Decrypt decrypts ciphertext to plaintext +// Decrypt decrypts ciphertext to plaintext. func Decrypt(ciphertext []byte) ([]byte, error) { block, err := aes.NewCipher(secretKey) if err != nil { diff --git a/pkg/encrypt/encrypt_test.go b/pkg/encrypt/encrypt_test.go index 84c4d8da0e..c7393dbd46 100644 --- a/pkg/encrypt/encrypt_test.go +++ b/pkg/encrypt/encrypt_test.go @@ -27,8 +27,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testEncryptSuite struct { -} +type testEncryptSuite struct{} func (t *testEncryptSuite) TestSetSecretKey(c *C) { // 16 bit diff --git a/pkg/etcdutil/etcdutil.go b/pkg/etcdutil/etcdutil.go index 6d8c9b9b51..f5d4da866c 100644 --- a/pkg/etcdutil/etcdutil.go +++ b/pkg/etcdutil/etcdutil.go @@ -100,7 +100,7 @@ func RemoveMember(client *clientv3.Client, id uint64) (*clientv3.MemberRemoveRes } // DoOpsInOneTxnWithRetry do multiple etcd operations in one txn. -// TODO: add unit test to test encountered an retryable error first but then recovered +// TODO: add unit test to test encountered an retryable error first but then recovered. func DoOpsInOneTxnWithRetry(cli *clientv3.Client, ops ...clientv3.Op) (*clientv3.TxnResponse, int64, error) { ctx, cancel := context.WithTimeout(cli.Ctx(), DefaultRequestTimeout) defer cancel() @@ -112,7 +112,6 @@ func DoOpsInOneTxnWithRetry(cli *clientv3.Client, ops ...clientv3.Op) (*clientv3 } return resp, nil }) - if err != nil { return nil, 0, err } @@ -137,7 +136,6 @@ func DoOpsInOneCmpsTxnWithRetry(cli *clientv3.Client, cmps []clientv3.Cmp, opsTh } return resp, nil }) - if err != nil { return nil, 0, err } @@ -145,7 +143,7 @@ func DoOpsInOneCmpsTxnWithRetry(cli *clientv3.Client, cmps []clientv3.Cmp, opsTh return resp, resp.Header.Revision, nil } -// IsRetryableError check whether error is retryable error for etcd to build again +// IsRetryableError check whether error is retryable error for etcd to build again. func IsRetryableError(err error) bool { switch errors.Cause(err) { case v3rpc.ErrCompacted, v3rpc.ErrNoLeader, v3rpc.ErrNoSpace, context.DeadlineExceeded: @@ -155,7 +153,7 @@ func IsRetryableError(err error) bool { } } -// IsLimitedRetryableError check whether error is retryable error for etcd to build again in a limited number of times +// IsLimitedRetryableError check whether error is retryable error for etcd to build again in a limited number of times. func IsLimitedRetryableError(err error) bool { switch errors.Cause(err) { case v3rpc.ErrNoSpace, context.DeadlineExceeded: diff --git a/pkg/etcdutil/etcdutil_test.go b/pkg/etcdutil/etcdutil_test.go index c6c0a64510..9103805c5a 100644 --- a/pkg/etcdutil/etcdutil_test.go +++ b/pkg/etcdutil/etcdutil_test.go @@ -37,8 +37,7 @@ var _ = Suite(&testEtcdUtilSuite{}) var tt *testing.T -type testEtcdUtilSuite struct { -} +type testEtcdUtilSuite struct{} func (t *testEtcdUtilSuite) SetUpSuite(c *C) { // initialized the logger to make genEmbedEtcdConfig working. @@ -84,9 +83,9 @@ func (t *testEtcdUtilSuite) newConfig(c *C, name string, basePort uint16, portCo return cfg, basePort } -func (t *testEtcdUtilSuite) urlsToStrings(URLs []url.URL) []string { - ret := make([]string, 0, len(URLs)) - for _, u := range URLs { +func (t *testEtcdUtilSuite) urlsToStrings(urls []url.URL) []string { + ret := make([]string, 0, len(urls)) + for _, u := range urls { ret = append(ret, u.String()) } return ret @@ -223,7 +222,8 @@ func (t *testEtcdUtilSuite) testDoOpsInOneTxnWithRetry(c *C) { cmp1 := clientv3.Compare(clientv3.Value(key1), "=", val1) cmp2 := clientv3.Compare(clientv3.Value(key2), "=", val2) resp, rev2, err := DoOpsInOneCmpsTxnWithRetry(cli, []clientv3.Cmp{cmp1, cmp2}, []clientv3.Op{ - clientv3.OpPut(key1, val), clientv3.OpPut(key2, val)}, []clientv3.Op{}) + clientv3.OpPut(key1, val), clientv3.OpPut(key2, val), + }, []clientv3.Op{}) c.Assert(err, IsNil) c.Assert(rev2, Greater, rev1) c.Assert(resp.Responses, HasLen, 2) @@ -232,7 +232,8 @@ func (t *testEtcdUtilSuite) testDoOpsInOneTxnWithRetry(c *C) { cmp1 = clientv3.Compare(clientv3.Value(key1), "=", val) cmp2 = clientv3.Compare(clientv3.Value(key2), "=", val2) resp, rev3, err := DoOpsInOneCmpsTxnWithRetry(cli, []clientv3.Cmp{cmp1, cmp2}, []clientv3.Op{}, []clientv3.Op{ - clientv3.OpDelete(key1), clientv3.OpDelete(key2)}) + clientv3.OpDelete(key1), clientv3.OpDelete(key2), + }) c.Assert(err, IsNil) c.Assert(rev3, Greater, rev2) c.Assert(resp.Responses, HasLen, 2) @@ -244,7 +245,8 @@ func (t *testEtcdUtilSuite) testDoOpsInOneTxnWithRetry(c *C) { // put again resp, rev2, err = DoOpsInOneCmpsTxnWithRetry(cli, []clientv3.Cmp{clientv3util.KeyMissing(key1), clientv3util.KeyMissing(key2)}, []clientv3.Op{ - clientv3.OpPut(key1, val), clientv3.OpPut(key2, val)}, []clientv3.Op{}) + clientv3.OpPut(key1, val), clientv3.OpPut(key2, val), + }, []clientv3.Op{}) c.Assert(err, IsNil) c.Assert(rev2, Greater, rev1) c.Assert(resp.Responses, HasLen, 2) diff --git a/pkg/func-rollback/rollback.go b/pkg/func-rollback/rollback.go index 36e5b3287c..34b4fba774 100644 --- a/pkg/func-rollback/rollback.go +++ b/pkg/func-rollback/rollback.go @@ -50,7 +50,7 @@ func (h *FuncRollbackHolder) Add(fn FuncRollback) { h.fns = append(h.fns, fn) } -// RollbackReverseOrder executes rollback functions in reverse order +// RollbackReverseOrder executes rollback functions in reverse order. func (h *FuncRollbackHolder) RollbackReverseOrder() { h.mu.Lock() defer h.mu.Unlock() diff --git a/pkg/func-rollback/rollback_test.go b/pkg/func-rollback/rollback_test.go index 388f8962b9..8630aa2238 100644 --- a/pkg/func-rollback/rollback_test.go +++ b/pkg/func-rollback/rollback_test.go @@ -26,8 +26,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testRollbackSuite struct { -} +type testRollbackSuite struct{} func (t *testRollbackSuite) TestRollback(c *C) { var ( diff --git a/pkg/gtid/gtid.go b/pkg/gtid/gtid.go index 6381d1df93..0eff06e49e 100644 --- a/pkg/gtid/gtid.go +++ b/pkg/gtid/gtid.go @@ -20,7 +20,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// Set provide gtid operations for syncer +// Set provide gtid operations for syncer. type Set interface { Set(mysql.GTIDSet) error // compute set of self and other gtid set @@ -45,7 +45,7 @@ type Set interface { String() string } -// ParserGTID parses GTID from string +// ParserGTID parses GTID from string. func ParserGTID(flavor, gtidStr string) (Set, error) { var ( m Set @@ -88,7 +88,7 @@ func ParserGTID(flavor, gtidStr string) (Set, error) { return m, err } -// MinGTIDSet returns the min GTID set +// MinGTIDSet returns the min GTID set. func MinGTIDSet(flavor string) Set { // use mysql as default if flavor != mysql.MariaDBFlavor && flavor != mysql.MySQLFlavor { @@ -106,12 +106,12 @@ func MinGTIDSet(flavor string) Set { /************************ mysql gtid set ***************************/ // MySQLGTIDSet wraps mysql.MysqlGTIDSet to implement gtidSet interface -// extend some functions to retrieve and compute an intersection with other MySQL GTID Set +// extend some functions to retrieve and compute an intersection with other MySQL GTID Set. type MySQLGTIDSet struct { set *mysql.MysqlGTIDSet } -// Set implements Set.Set, replace g by other +// Set implements Set.Set, replace g by other. func (g *MySQLGTIDSet) Set(other mysql.GTIDSet) error { if other == nil { return nil @@ -126,7 +126,7 @@ func (g *MySQLGTIDSet) Set(other mysql.GTIDSet) error { return nil } -// Replace implements Set.Replace +// Replace implements Set.Replace. func (g *MySQLGTIDSet) Replace(other Set, masters []interface{}) error { if other == nil { return nil @@ -169,7 +169,7 @@ func (g *MySQLGTIDSet) get(uuid string) (*mysql.UUIDSet, bool) { return uuidSet, ok } -// Clone implements Set.Clone +// Clone implements Set.Clone. func (g *MySQLGTIDSet) Clone() Set { if g.set == nil { return MinGTIDSet(mysql.MySQLFlavor) @@ -180,7 +180,7 @@ func (g *MySQLGTIDSet) Clone() Set { } } -// Origin implements Set.Origin +// Origin implements Set.Origin. func (g *MySQLGTIDSet) Origin() mysql.GTIDSet { if g.set == nil { return &mysql.MysqlGTIDSet{} @@ -188,7 +188,7 @@ func (g *MySQLGTIDSet) Origin() mysql.GTIDSet { return g.set.Clone().(*mysql.MysqlGTIDSet) } -// Equal implements Set.Equal +// Equal implements Set.Equal. func (g *MySQLGTIDSet) Equal(other Set) bool { otherIsNil := other == nil if !otherIsNil { @@ -208,7 +208,7 @@ func (g *MySQLGTIDSet) Equal(other Set) bool { return g.set.Equal(other.Origin()) } -// Contain implements Set.Contain +// Contain implements Set.Contain. func (g *MySQLGTIDSet) Contain(other Set) bool { otherIsNil := other == nil if !otherIsNil { @@ -226,7 +226,7 @@ func (g *MySQLGTIDSet) Contain(other Set) bool { return g.set.Contain(other.Origin()) } -// Truncate implements Set.Truncate +// Truncate implements Set.Truncate. func (g *MySQLGTIDSet) Truncate(end Set) error { if end == nil { return nil // do nothing @@ -267,12 +267,12 @@ func (g *MySQLGTIDSet) String() string { /************************ mariadb gtid set ***************************/ // MariadbGTIDSet wraps mysql.MariadbGTIDSet to implement gtidSet interface -// extend some functions to retrieve and compute an intersection with other Mariadb GTID Set +// extend some functions to retrieve and compute an intersection with other Mariadb GTID Set. type MariadbGTIDSet struct { set *mysql.MariadbGTIDSet } -// Set implements Set.Set, replace g by other +// Set implements Set.Set, replace g by other. func (m *MariadbGTIDSet) Set(other mysql.GTIDSet) error { if other == nil { return nil @@ -287,7 +287,7 @@ func (m *MariadbGTIDSet) Set(other mysql.GTIDSet) error { return nil } -// Replace implements Set.Replace +// Replace implements Set.Replace. func (m *MariadbGTIDSet) Replace(other Set, masters []interface{}) error { if other == nil { return nil @@ -336,7 +336,7 @@ func (m *MariadbGTIDSet) get(domainID uint32) (*mysql.MariadbGTID, bool) { return gtid, ok } -// Clone implements Set.Clone +// Clone implements Set.Clone. func (m *MariadbGTIDSet) Clone() Set { if m.set == nil { return MinGTIDSet(mysql.MariaDBFlavor) @@ -346,7 +346,7 @@ func (m *MariadbGTIDSet) Clone() Set { } } -// Origin implements Set.Origin +// Origin implements Set.Origin. func (m *MariadbGTIDSet) Origin() mysql.GTIDSet { if m.set == nil { return &mysql.MariadbGTIDSet{} @@ -354,7 +354,7 @@ func (m *MariadbGTIDSet) Origin() mysql.GTIDSet { return m.set.Clone().(*mysql.MariadbGTIDSet) } -// Equal implements Set.Equal +// Equal implements Set.Equal. func (m *MariadbGTIDSet) Equal(other Set) bool { otherIsNil := other == nil if !otherIsNil { @@ -374,7 +374,7 @@ func (m *MariadbGTIDSet) Equal(other Set) bool { return m.set.Equal(other.Origin()) } -// Contain implements Set.Contain +// Contain implements Set.Contain. func (m *MariadbGTIDSet) Contain(other Set) bool { otherIsNil := other == nil if !otherIsNil { @@ -392,7 +392,7 @@ func (m *MariadbGTIDSet) Contain(other Set) bool { return m.set.Contain(other.Origin()) } -// Truncate implements Set.Truncate +// Truncate implements Set.Truncate. func (m *MariadbGTIDSet) Truncate(end Set) error { if end == nil { return nil // do nothing diff --git a/pkg/gtid/gtid_test.go b/pkg/gtid/gtid_test.go index e1d8b4086a..638b65249d 100644 --- a/pkg/gtid/gtid_test.go +++ b/pkg/gtid/gtid_test.go @@ -29,8 +29,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testGTIDSuite struct { -} +type testGTIDSuite struct{} func (s *testGTIDSuite) TestGTID(c *C) { matserUUIDs := []string{ @@ -153,6 +152,7 @@ func (s *testGTIDSuite) TestMariaGTIDEqual(c *C) { c.Assert(g1.Equal(g2), IsTrue) } +// nolint:dupl func (s *testGTIDSuite) TestMySQLGTIDContain(c *C) { var ( g1 *MySQLGTIDSet @@ -184,6 +184,7 @@ func (s *testGTIDSuite) TestMySQLGTIDContain(c *C) { c.Assert(g2.Contain(g1), IsFalse) } +// nolint:dupl func (s *testGTIDSuite) TestMairaGTIDContain(c *C) { var ( g1 *MariadbGTIDSet diff --git a/pkg/ha/bound.go b/pkg/ha/bound.go index 43b9bd1b01..1d7eb67516 100644 --- a/pkg/ha/bound.go +++ b/pkg/ha/bound.go @@ -33,7 +33,7 @@ import ( const ( // we need two steps to get a name/id and query config using that id. // since above steps can't be put into one etcd transaction, we combine and re-run the first step into the second - // step, and check the name/id is still valid. if not valid, retry the second step using new name/id + // step, and check the name/id is still valid. if not valid, retry the second step using new name/id. defaultGetSourceBoundConfigRetry = 3 defaultGetRelayConfigRetry = 3 retryInterval = 50 * time.Millisecond // retry interval when we get two different bounds @@ -74,7 +74,7 @@ func (b SourceBound) toJSON() (string, error) { return string(data), nil } -// IsEmpty returns true when this bound has no value +// IsEmpty returns true when this bound has no value. func (b SourceBound) IsEmpty() bool { var emptyBound SourceBound return b == emptyBound @@ -112,7 +112,7 @@ func DeleteSourceBound(cli *clientv3.Client, workers ...string) (int64, error) { } // ReplaceSourceBound deletes an old bound and puts a new bound in one transaction, so a bound source will not become -// unbound because of failing halfway +// unbound because of failing halfway. func ReplaceSourceBound(cli *clientv3.Client, source, oldWorker, newWorker string) (int64, error) { deleteOps := deleteSourceBoundOp(oldWorker) putOps, err := putSourceBoundOp(NewSourceBound(source, newWorker)) @@ -161,16 +161,13 @@ func GetSourceBound(cli *clientv3.Client, worker string) (map[string]SourceBound } // GetLastSourceBounds gets all last source bound relationship. Different with GetSourceBound, "last source bound" will -// not be deleted when worker offline +// not be deleted when worker offline. func GetLastSourceBounds(cli *clientv3.Client) (map[string]SourceBound, int64, error) { ctx, cancel := context.WithTimeout(cli.Ctx(), etcdutil.DefaultRequestTimeout) defer cancel() - var ( - sbm = make(map[string]SourceBound) - ) + sbm := make(map[string]SourceBound) resp, err := cli.Get(ctx, common.UpstreamLastBoundWorkerKeyAdapter.Path(), clientv3.WithPrefix()) - if err != nil { return sbm, 0, err } @@ -187,7 +184,7 @@ func GetLastSourceBounds(cli *clientv3.Client) (map[string]SourceBound, int64, e // for the specified DM-worker. The index worker **must not be empty**: // if source bound is empty, will return an empty sourceBound and an empty source config // if source bound is not empty but sourceConfig is empty, will return an error -// if the source bound is different for over retryNum times, will return an error +// if the source bound is different for over retryNum times, will return an error. func GetSourceBoundConfig(cli *clientv3.Client, worker string) (SourceBound, config.SourceConfig, int64, error) { var ( bound SourceBound @@ -261,6 +258,7 @@ func GetSourceBoundConfig(cli *clientv3.Client, worker string) (SourceBound, con // WatchSourceBound watches PUT & DELETE operations for the bound relationship of the specified DM-worker. // For the DELETE operations, it returns an empty bound relationship. +// nolint:dupl func WatchSourceBound(ctx context.Context, cli *clientv3.Client, worker string, revision int64, outCh chan<- SourceBound, errCh chan<- error) { ch := cli.Watch(ctx, common.UpstreamBoundWorkerKeyAdapter.Encode(worker), clientv3.WithRev(revision)) diff --git a/pkg/ha/bound_test.go b/pkg/ha/bound_test.go index 7ba9883adb..fa95f6c0b7 100644 --- a/pkg/ha/bound_test.go +++ b/pkg/ha/bound_test.go @@ -144,6 +144,7 @@ func (t *testForEtcd) TestGetSourceBoundConfigEtcd(c *C) { c.Assert(err, IsNil) c.Assert(rev2, Greater, rev1) // get source bound and config, but config is empty + // nolint:dogsled _, _, _, err = GetSourceBoundConfig(etcdTestCli, worker) c.Assert(err, ErrorMatches, ".*doesn't have related source config in etcd.*") diff --git a/pkg/ha/keepalive.go b/pkg/ha/keepalive.go index d34c1c6303..249871da1e 100644 --- a/pkg/ha/keepalive.go +++ b/pkg/ha/keepalive.go @@ -29,9 +29,9 @@ import ( ) var ( - // currentKeepAliveTTL may be assigned to KeepAliveTTL or RelayKeepAliveTTL + // currentKeepAliveTTL may be assigned to KeepAliveTTL or RelayKeepAliveTTL. currentKeepAliveTTL int64 - // KeepAliveUpdateCh is used to notify keepalive TTL changing, in order to let watcher not see a DELETE of old key + // KeepAliveUpdateCh is used to notify keepalive TTL changing, in order to let watcher not see a DELETE of old key. KeepAliveUpdateCh = make(chan int64, 10) ) @@ -181,7 +181,8 @@ func KeepAlive(ctx context.Context, cli *clientv3.Client, workerName string, kee } // ATTENTION!!! we must ensure cli.Ctx() not done when we are exiting worker -// Do not set cfg.Context when creating cli or do not cancel this Context or it's parent context +// Do not set cfg.Context when creating cli or do not cancel this Context or it's parent context. +// nolint:unparam func revokeLease(cli *clientv3.Client, id clientv3.LeaseID) (*clientv3.LeaseRevokeResponse, error) { ctx, cancel := context.WithTimeout(cli.Ctx(), etcdutil.DefaultRevokeLeaseTimeout) defer cancel() @@ -189,7 +190,7 @@ func revokeLease(cli *clientv3.Client, id clientv3.LeaseID) (*clientv3.LeaseRevo } // WatchWorkerEvent watches the online and offline of workers from etcd. -// this function will output the worker event to evCh, output the error to errCh +// this function will output the worker event to evCh, output the error to errCh. func WatchWorkerEvent(ctx context.Context, cli *clientv3.Client, rev int64, outCh chan<- WorkerEvent, errCh chan<- error) { watcher := clientv3.NewWatcher(cli) ch := watcher.Watch(ctx, common.WorkerKeepAliveKeyAdapter.Path(), clientv3.WithPrefix(), clientv3.WithRev(rev)) @@ -247,7 +248,7 @@ func WatchWorkerEvent(ctx context.Context, cli *clientv3.Client, rev int64, outC } // GetKeepAliveWorkers gets current alive workers, -// and returns a map{workerName: WorkerEvent}, revision and error +// and returns a map{workerName: WorkerEvent}, revision and error. func GetKeepAliveWorkers(cli *clientv3.Client) (map[string]WorkerEvent, int64, error) { ctx, cancel := context.WithTimeout(cli.Ctx(), etcdutil.DefaultRequestTimeout) defer cancel() diff --git a/pkg/ha/keepalive_test.go b/pkg/ha/keepalive_test.go index ec5c9ef667..8f0546ff21 100644 --- a/pkg/ha/keepalive_test.go +++ b/pkg/ha/keepalive_test.go @@ -26,7 +26,7 @@ import ( ) // keepAliveTTL is set to 0 because the actual ttl is set to minLeaseTTL of etcd -// minLeaseTTL is 1 in etcd cluster +// minLeaseTTL is 1 in etcd cluster. var keepAliveTTL = int64(0) func (t *testForEtcd) TestWorkerKeepAlive(c *C) { diff --git a/pkg/ha/relay.go b/pkg/ha/relay.go index 6e995c2fb4..b75268aa3a 100644 --- a/pkg/ha/relay.go +++ b/pkg/ha/relay.go @@ -40,7 +40,7 @@ type RelaySource struct { // PutRelayConfig puts the relay config for given workers. // k/v: worker-name -> source-id. -// TODO: let caller wait until worker has enabled relay +// TODO: let caller wait until worker has enabled relay. func PutRelayConfig(cli *clientv3.Client, source string, workers ...string) (int64, error) { ops := make([]clientv3.Op, 0, len(workers)) for _, worker := range workers { @@ -96,7 +96,7 @@ func GetAllRelayConfig(cli *clientv3.Client) (map[string]map[string]struct{}, in return ret, resp.Header.Revision, nil } -// GetRelayConfig returns the source config which the given worker need to pull relay log from etcd, with revision +// GetRelayConfig returns the source config which the given worker need to pull relay log from etcd, with revision. func GetRelayConfig(cli *clientv3.Client, worker string) (*config.SourceConfig, int64, error) { var ( source string @@ -237,5 +237,4 @@ func WatchRelayConfig(ctx context.Context, cli *clientv3.Client, } } } - } diff --git a/pkg/ha/source.go b/pkg/ha/source.go index e31122cee5..de0d7c661f 100644 --- a/pkg/ha/source.go +++ b/pkg/ha/source.go @@ -98,7 +98,7 @@ func sourceCfgFromResp(source string, resp *clientv3.GetResponse) (map[string]co } // ClearTestInfoOperation is used to clear all DM-HA relative etcd keys' information -// this function shouldn't be used in development environment +// this function shouldn't be used in development environment. func ClearTestInfoOperation(cli *clientv3.Client) error { clearSource := clientv3.OpDelete(common.UpstreamConfigKeyAdapter.Path(), clientv3.WithPrefix()) clearTask := clientv3.OpDelete(common.TaskConfigKeyAdapter.Path(), clientv3.WithPrefix()) diff --git a/pkg/ha/source_test.go b/pkg/ha/source_test.go index b1b12db8c9..af7568c1e3 100644 --- a/pkg/ha/source_test.go +++ b/pkg/ha/source_test.go @@ -29,9 +29,7 @@ const ( sourceSampleFile = "../../dm/worker/source.yaml" ) -var ( - etcdTestCli *clientv3.Client -) +var etcdTestCli *clientv3.Client func TestHA(t *testing.T) { mockCluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) diff --git a/pkg/ha/stage.go b/pkg/ha/stage.go index a8dc2f2953..977b1fab4d 100644 --- a/pkg/ha/stage.go +++ b/pkg/ha/stage.go @@ -76,7 +76,7 @@ func (s Stage) toJSON() (string, error) { return string(data), nil } -// IsEmpty returns true when this Stage has no value +// IsEmpty returns true when this Stage has no value. func (s Stage) IsEmpty() bool { var emptyStage Stage return s == emptyStage @@ -99,7 +99,7 @@ func PutRelayStage(cli *clientv3.Client, stages ...Stage) (int64, error) { return rev, err } -// DeleteRelayStage deleted the relay stage of this source +// DeleteRelayStage deleted the relay stage of this source. func DeleteRelayStage(cli *clientv3.Client, source string) (int64, error) { _, rev, err := etcdutil.DoOpsInOneTxnWithRetry(cli, deleteRelayStageOp(source)) return rev, err @@ -322,6 +322,7 @@ func subTaskStageFromResp(source, task string, resp *clientv3.GetResponse) (map[ } // watchStage watches PUT & DELETE operations for the stage. +// nolint:dupl func watchStage(ctx context.Context, watchCh clientv3.WatchChan, stageFromKey func(key string) (Stage, error), outCh chan<- Stage, errCh chan<- error) { for { diff --git a/pkg/ha/subtask.go b/pkg/ha/subtask.go index e4b12d6b8b..c57025bcbb 100644 --- a/pkg/ha/subtask.go +++ b/pkg/ha/subtask.go @@ -27,7 +27,7 @@ import ( // GetSubTaskCfg gets the subtask config of the specified source and task name. // if the config for the source not exist, return with `err == nil` and `revision=0`. // if task name is "", will return all the subtaskConfigs as a map{taskName: subtaskConfig} of the source -// if task name if given, will return a map{taskName: subtaskConfig} whose length is 1 +// if task name if given, will return a map{taskName: subtaskConfig} whose length is 1. func GetSubTaskCfg(cli *clientv3.Client, source, task string, rev int64) (map[string]config.SubTaskConfig, int64, error) { ctx, cancel := context.WithTimeout(cli.Ctx(), etcdutil.DefaultRequestTimeout) defer cancel() @@ -57,13 +57,12 @@ func GetSubTaskCfg(cli *clientv3.Client, source, task string, rev int64) (map[st } // GetAllSubTaskCfg gets all subtask configs. -// k/v: source ID -> task name -> subtask config +// k/v: source ID -> task name -> subtask config. func GetAllSubTaskCfg(cli *clientv3.Client) (map[string]map[string]config.SubTaskConfig, int64, error) { ctx, cancel := context.WithTimeout(cli.Ctx(), etcdutil.DefaultRequestTimeout) defer cancel() resp, err := cli.Get(ctx, common.UpstreamSubTaskKeyAdapter.Path(), clientv3.WithPrefix()) - if err != nil { return nil, 0, err } diff --git a/pkg/helper/value_test.go b/pkg/helper/value_test.go index c43dfbd397..ef2241f34b 100644 --- a/pkg/helper/value_test.go +++ b/pkg/helper/value_test.go @@ -27,8 +27,7 @@ func TestSuite(t *testing.T) { var _ = check.Suite(&testValueSuite{}) -type testValueSuite struct { -} +type testValueSuite struct{} type fIsNil func() @@ -36,7 +35,7 @@ func fIsNil1() {} func (t *testValueSuite) TestIsNil(c *check.C) { // nil value - var i = 123 + i := 123 c.Assert(IsNil(nil), check.IsTrue) c.Assert(IsNil(i), check.IsFalse) @@ -58,13 +57,13 @@ func (t *testValueSuite) TestIsNil(c *check.C) { // pointer var piNil *int - var piNotNil = &i + piNotNil := &i c.Assert(IsNil(piNil), check.IsTrue) c.Assert(IsNil(piNotNil), check.IsFalse) // unsafe pointer var upiNil unsafe.Pointer - var upiNotNil = unsafe.Pointer(piNotNil) + upiNotNil := unsafe.Pointer(piNotNil) c.Assert(IsNil(upiNil), check.IsTrue) c.Assert(IsNil(upiNotNil), check.IsFalse) diff --git a/pkg/log/log.go b/pkg/log/log.go index 6c3cea44f8..404830a217 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -50,7 +50,7 @@ type Config struct { FileMaxBackups int `toml:"max-backups" json:"max-backups"` } -// Adjust adjusts config +// Adjust adjusts config. func (cfg *Config) Adjust() { if len(cfg.Level) == 0 { cfg.Level = defaultLogLevel @@ -72,12 +72,12 @@ type Logger struct { *zap.Logger } -// WithFields return new Logger with specified fields +// WithFields return new Logger with specified fields. func (l Logger) WithFields(fields ...zap.Field) Logger { return Logger{l.With(fields...)} } -// ErrorFilterContextCanceled wraps Logger.Error() and will filter error log when error is context.Canceled +// ErrorFilterContextCanceled wraps Logger.Error() and will filter error log when error is context.Canceled. func (l Logger) ErrorFilterContextCanceled(msg string, fields ...zap.Field) { for _, field := range fields { switch field.Type { @@ -95,7 +95,7 @@ func (l Logger) ErrorFilterContextCanceled(msg string, fields ...zap.Field) { l.Logger.WithOptions(zap.AddCallerSkip(1)).Error(msg, fields...) } -// logger for DM +// logger for DM. var ( appLogger = Logger{zap.NewNop()} appLevel zap.AtomicLevel @@ -170,7 +170,7 @@ func Props() *pclog.ZapProperties { return appProps } -// WrapStringerField returns a wrap stringer field +// WrapStringerField returns a wrap stringer field. func WrapStringerField(message string, object fmt.Stringer) zap.Field { if helper.IsNil(object) { return zap.String(message, "NULL") diff --git a/pkg/metricsproxy/countervec.go b/pkg/metricsproxy/countervec.go index d33faa1de0..fe5fe6139d 100644 --- a/pkg/metricsproxy/countervec.go +++ b/pkg/metricsproxy/countervec.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "sync" @@ -19,7 +19,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -// CounterVecProxy to proxy prometheus.CounterVec +// CounterVecProxy to proxy prometheus.CounterVec. type CounterVecProxy struct { mu sync.Mutex @@ -69,7 +69,7 @@ func (c *CounterVecProxy) With(labels prometheus.Labels) prometheus.Counter { return c.CounterVec.With(labels) } -// DeleteAllAboutLabels Remove all labelsValue with these labels +// DeleteAllAboutLabels Remove all labelsValue with these labels. func (c *CounterVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool { if len(labels) == 0 { return false @@ -79,24 +79,24 @@ func (c *CounterVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool { return findAndDeleteLabelsInMetricsProxy(c, labels) } -// GetLabelNamesIndex to support get CounterVecProxy's LabelNames when you use Proxy object +// GetLabelNamesIndex to support get CounterVecProxy's LabelNames when you use Proxy object. func (c *CounterVecProxy) GetLabelNamesIndex() map[string]int { return c.LabelNamesIndex } -// GetLabels to support get CounterVecProxy's Labels when you use Proxy object +// GetLabels to support get CounterVecProxy's Labels when you use Proxy object. func (c *CounterVecProxy) GetLabels() map[string][]string { return c.Labels } -// SetLabel to support set CounterVecProxy's Label when you use Proxy object +// SetLabel to support set CounterVecProxy's Label when you use Proxy object. func (c *CounterVecProxy) SetLabel(key string, vals []string) { c.mu.Lock() defer c.mu.Unlock() c.Labels[key] = vals } -// vecDelete to support delete CounterVecProxy's Labels when you use Proxy object +// vecDelete to support delete CounterVecProxy's Labels when you use Proxy object. func (c *CounterVecProxy) vecDelete(labels prometheus.Labels) bool { return c.CounterVec.Delete(labels) } diff --git a/pkg/metricsproxy/countervec_test.go b/pkg/metricsproxy/countervec_test.go index a165abee84..ce62f4fdb5 100644 --- a/pkg/metricsproxy/countervec_test.go +++ b/pkg/metricsproxy/countervec_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "math/rand" diff --git a/pkg/metricsproxy/gaugevec.go b/pkg/metricsproxy/gaugevec.go index 4d2c6100ce..081940d207 100644 --- a/pkg/metricsproxy/gaugevec.go +++ b/pkg/metricsproxy/gaugevec.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "sync" @@ -19,7 +19,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -// GaugeVecProxy to proxy prometheus.GaugeVec +// GaugeVecProxy to proxy prometheus.GaugeVec. type GaugeVecProxy struct { mu sync.Mutex @@ -69,7 +69,7 @@ func (c *GaugeVecProxy) With(labels prometheus.Labels) prometheus.Gauge { return c.GaugeVec.With(labels) } -// DeleteAllAboutLabels Remove all labelsValue with these labels +// DeleteAllAboutLabels Remove all labelsValue with these labels. func (c *GaugeVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool { if len(labels) == 0 { return false @@ -79,24 +79,24 @@ func (c *GaugeVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool { return findAndDeleteLabelsInMetricsProxy(c, labels) } -// GetLabelNamesIndex to support get GaugeVecProxy's LabelNames when you use Proxy object +// GetLabelNamesIndex to support get GaugeVecProxy's LabelNames when you use Proxy object. func (c *GaugeVecProxy) GetLabelNamesIndex() map[string]int { return c.LabelNamesIndex } -// GetLabels to support get GaugeVecProxy's Labels when you use Proxy object +// GetLabels to support get GaugeVecProxy's Labels when you use Proxy object. func (c *GaugeVecProxy) GetLabels() map[string][]string { return c.Labels } -// SetLabel to support set GaugeVecProxy's Label when you use Proxy object +// SetLabel to support set GaugeVecProxy's Label when you use Proxy object. func (c *GaugeVecProxy) SetLabel(key string, vals []string) { c.mu.Lock() defer c.mu.Unlock() c.Labels[key] = vals } -// vecDelete to support delete GaugeVecProxy's Labels when you use Proxy object +// vecDelete to support delete GaugeVecProxy's Labels when you use Proxy object. func (c *GaugeVecProxy) vecDelete(labels prometheus.Labels) bool { return c.GaugeVec.Delete(labels) } diff --git a/pkg/metricsproxy/gaugevec_test.go b/pkg/metricsproxy/gaugevec_test.go index 32328a4fe5..03f7e4fd44 100644 --- a/pkg/metricsproxy/gaugevec_test.go +++ b/pkg/metricsproxy/gaugevec_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "math/rand" diff --git a/pkg/metricsproxy/histogramvec.go b/pkg/metricsproxy/histogramvec.go index 0ddb8b031d..639274fc2a 100644 --- a/pkg/metricsproxy/histogramvec.go +++ b/pkg/metricsproxy/histogramvec.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "sync" @@ -19,7 +19,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -// HistogramVecProxy to proxy prometheus.HistogramVec +// HistogramVecProxy to proxy prometheus.HistogramVec. type HistogramVecProxy struct { mu sync.Mutex @@ -69,7 +69,7 @@ func (c *HistogramVecProxy) With(labels prometheus.Labels) prometheus.Observer { return c.HistogramVec.With(labels) } -// DeleteAllAboutLabels Remove all labelsValue with these labels +// DeleteAllAboutLabels Remove all labelsValue with these labels. func (c *HistogramVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool { if len(labels) == 0 { return false @@ -79,24 +79,24 @@ func (c *HistogramVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool return findAndDeleteLabelsInMetricsProxy(c, labels) } -// GetLabelNamesIndex to support get HistogramVecProxy's LabelNames when you use Proxy object +// GetLabelNamesIndex to support get HistogramVecProxy's LabelNames when you use Proxy object. func (c *HistogramVecProxy) GetLabelNamesIndex() map[string]int { return c.LabelNamesIndex } -// GetLabels to support get HistogramVecProxy's Labels when you use Proxy object +// GetLabels to support get HistogramVecProxy's Labels when you use Proxy object. func (c *HistogramVecProxy) GetLabels() map[string][]string { return c.Labels } -// SetLabel to support set HistogramVecProxy's Label when you use Proxy object +// SetLabel to support set HistogramVecProxy's Label when you use Proxy object. func (c *HistogramVecProxy) SetLabel(key string, vals []string) { c.mu.Lock() defer c.mu.Unlock() c.Labels[key] = vals } -// vecDelete to support delete HistogramVecProxy's Labels when you use Proxy object +// vecDelete to support delete HistogramVecProxy's Labels when you use Proxy object. func (c *HistogramVecProxy) vecDelete(labels prometheus.Labels) bool { return c.HistogramVec.Delete(labels) } diff --git a/pkg/metricsproxy/histogramvec_test.go b/pkg/metricsproxy/histogramvec_test.go index 31f1d5bc51..2fd151b01c 100644 --- a/pkg/metricsproxy/histogramvec_test.go +++ b/pkg/metricsproxy/histogramvec_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "math/rand" diff --git a/pkg/metricsproxy/proxy.go b/pkg/metricsproxy/proxy.go index 3dba27f047..7190bd92bf 100644 --- a/pkg/metricsproxy/proxy.go +++ b/pkg/metricsproxy/proxy.go @@ -19,7 +19,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -// Proxy Interface +// Proxy Interface. type Proxy interface { GetLabelNamesIndex() map[string]int GetLabels() map[string][]string @@ -27,13 +27,13 @@ type Proxy interface { vecDelete(prometheus.Labels) bool } -// noteLabelsInMetricsProxy common function in Proxy +// noteLabelsInMetricsProxy common function in Proxy. func noteLabelsInMetricsProxy(proxy Proxy, values []string) { key := strings.Join(values, ",") proxy.SetLabel(key, values) } -// findAndDeleteLabelsInMetricsProxy common function in Proxy +// findAndDeleteLabelsInMetricsProxy common function in Proxy. func findAndDeleteLabelsInMetricsProxy(proxy Proxy, labels prometheus.Labels) bool { var ( deleteLabelsList = make([]map[string]string, 0) diff --git a/pkg/metricsproxy/proxy_test.go b/pkg/metricsproxy/proxy_test.go index 8381b6bc90..42ec62b799 100644 --- a/pkg/metricsproxy/proxy_test.go +++ b/pkg/metricsproxy/proxy_test.go @@ -25,8 +25,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testMetricsProxySuite struct { -} +type testMetricsProxySuite struct{} type testCase struct { LabelsNames []string diff --git a/pkg/metricsproxy/summaryvec.go b/pkg/metricsproxy/summaryvec.go index 199c9dc1a1..7d98fbae82 100644 --- a/pkg/metricsproxy/summaryvec.go +++ b/pkg/metricsproxy/summaryvec.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "sync" @@ -19,7 +19,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -// SummaryVecProxy to proxy prometheus.SummaryVec +// SummaryVecProxy to proxy prometheus.SummaryVec. type SummaryVecProxy struct { mu sync.Mutex @@ -73,7 +73,7 @@ func (c *SummaryVecProxy) With(labels prometheus.Labels) prometheus.Observer { return c.SummaryVec.With(labels) } -// DeleteAllAboutLabels Remove all labelsValue with these labels +// DeleteAllAboutLabels Remove all labelsValue with these labels. func (c *SummaryVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool { if len(labels) == 0 { return false @@ -83,24 +83,24 @@ func (c *SummaryVecProxy) DeleteAllAboutLabels(labels prometheus.Labels) bool { return findAndDeleteLabelsInMetricsProxy(c, labels) } -// GetLabelNamesIndex to support get SummaryVecProxy's LabelNames when you use Proxy object +// GetLabelNamesIndex to support get SummaryVecProxy's LabelNames when you use Proxy object. func (c *SummaryVecProxy) GetLabelNamesIndex() map[string]int { return c.LabelNamesIndex } -// GetLabels to support get SummaryVecProxy's Labels when you use Proxy object +// GetLabels to support get SummaryVecProxy's Labels when you use Proxy object. func (c *SummaryVecProxy) GetLabels() map[string][]string { return c.Labels } -// SetLabel to support set SummaryVecProxy's Label when you use Proxy object +// SetLabel to support set SummaryVecProxy's Label when you use Proxy object. func (c *SummaryVecProxy) SetLabel(key string, vals []string) { c.mu.Lock() defer c.mu.Unlock() c.Labels[key] = vals } -// vecDelete to support delete SummaryVecProxy's Labels when you use Proxy object +// vecDelete to support delete SummaryVecProxy's Labels when you use Proxy object. func (c *SummaryVecProxy) vecDelete(labels prometheus.Labels) bool { return c.SummaryVec.Delete(labels) } diff --git a/pkg/metricsproxy/summaryvec_test.go b/pkg/metricsproxy/summaryvec_test.go index abbf4d273b..f3edaa9515 100644 --- a/pkg/metricsproxy/summaryvec_test.go +++ b/pkg/metricsproxy/summaryvec_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metricsproxy +package metricsproxy // nolint:dupl import ( "math/rand" diff --git a/pkg/parser/common.go b/pkg/parser/common.go index 9128fa7d0c..028170bb63 100644 --- a/pkg/parser/common.go +++ b/pkg/parser/common.go @@ -34,7 +34,7 @@ const ( SingleRenameTableNameNum = 2 ) -// Parse wraps parser.Parse(), makes `parser` suitable for dm +// Parse wraps parser.Parse(), makes `parser` suitable for dm. func Parse(p *parser.Parser, sql, charset, collation string) (stmt []ast.StmtNode, err error) { stmts, warnings, err := p.Parse(sql, charset, collation) if len(warnings) > 0 { @@ -70,7 +70,7 @@ func (tne *tableNameExtractor) Leave(in ast.Node) (ast.Node, bool) { // Because we use visitor pattern, first tableName is always upper-most table in ast // specifically, for `create table like` DDL, result contains [sourceTableName, sourceRefTableName] // for rename table ddl, result contains [old1, new1, old1, new1, old2, new2, old3, new3, ...] because of TiDB parser -// for other DDL, order of tableName is the node visit order +// for other DDL, order of tableName is the node visit order. func FetchDDLTableNames(schema string, stmt ast.StmtNode) ([]*filter.Table, error) { switch stmt.(type) { case ast.DDLNode: @@ -129,7 +129,7 @@ func (v *tableRenameVisitor) Leave(in ast.Node) (ast.Node, bool) { // RenameDDLTable renames table names in ddl by given `targetTableNames` // argument `targetTableNames` is same with return value of FetchDDLTableNames -// returned DDL is formatted like StringSingleQuotes, KeyWordUppercase and NameBackQuotes +// returned DDL is formatted like StringSingleQuotes, KeyWordUppercase and NameBackQuotes. func RenameDDLTable(stmt ast.StmtNode, targetTableNames []*filter.Table) (string, error) { switch stmt.(type) { case ast.DDLNode: @@ -169,7 +169,7 @@ func RenameDDLTable(stmt ast.StmtNode, targetTableNames []*filter.Table) (string // SplitDDL splits multiple operations in one DDL statement into multiple DDL statements // returned DDL is formatted like StringSingleQuotes, KeyWordUppercase and NameBackQuotes -// if fail to restore, it would not restore the value of `stmt` (it changes it's values if `stmt` is one of DropTableStmt, RenameTableStmt, AlterTableStmt) +// if fail to restore, it would not restore the value of `stmt` (it changes it's values if `stmt` is one of DropTableStmt, RenameTableStmt, AlterTableStmt). func SplitDDL(stmt ast.StmtNode, schema string) (sqls []string, err error) { var ( schemaName = model.NewCIStr(schema) // fill schema name diff --git a/pkg/parser/common_test.go b/pkg/parser/common_test.go index 39fab42edb..c29fbe520e 100644 --- a/pkg/parser/common_test.go +++ b/pkg/parser/common_test.go @@ -338,8 +338,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testParserSuite struct { -} +type testParserSuite struct{} func (t *testParserSuite) TestParser(c *C) { p := parser.New() diff --git a/pkg/retry/errors.go b/pkg/retry/errors.go index 7810de8d7e..22cd32d76d 100644 --- a/pkg/retry/errors.go +++ b/pkg/retry/errors.go @@ -25,7 +25,7 @@ import ( // some error reference: https://docs.pingcap.com/tidb/stable/tidb-limitations#limitations-on-a-single-table var ( - // UnsupportedDDLMsgs list the error messages of some unsupported DDL in TiDB + // UnsupportedDDLMsgs list the error messages of some unsupported DDL in TiDB. UnsupportedDDLMsgs = []string{ "can't drop column with index", "unsupported add column", @@ -41,7 +41,7 @@ var ( "Error 1069: Too many keys specified", } - // UnsupportedDMLMsgs list the error messages of some un-recoverable DML, which is used in task auto recovery + // UnsupportedDMLMsgs list the error messages of some un-recoverable DML, which is used in task auto recovery. UnsupportedDMLMsgs = []string{ "Error 1062: Duplicate", "Error 1406: Data too long for column", @@ -49,7 +49,7 @@ var ( "Error 8025: entry too large", } - // ReplicationErrMsgs list the error message of un-recoverable replication error + // ReplicationErrMsgs list the error message of un-recoverable replication error. ReplicationErrMsgs = []string{ "Could not find first log file name in binary log index file", } @@ -78,7 +78,7 @@ var ( } ) -// IsConnectionError tells whether this error should reconnect to Database +// IsConnectionError tells whether this error should reconnect to Database. func IsConnectionError(err error) bool { err = errors.Cause(err) switch err { diff --git a/pkg/retry/strategy.go b/pkg/retry/strategy.go index 798298e14e..8724638c8e 100644 --- a/pkg/retry/strategy.go +++ b/pkg/retry/strategy.go @@ -19,18 +19,18 @@ import ( tcontext "github.com/pingcap/dm/pkg/context" ) -// backoffStrategy represents enum of retry wait interval +// backoffStrategy represents enum of retry wait interval. type backoffStrategy uint8 const ( - // Stable represents fixed time wait retry policy, every retry should wait a fixed time + // Stable represents fixed time wait retry policy, every retry should wait a fixed time. Stable backoffStrategy = iota + 1 - // LinearIncrease represents increase time wait retry policy, every retry should wait more time depends on increasing retry times + // LinearIncrease represents increase time wait retry policy, every retry should wait more time depends on increasing retry times. LinearIncrease ) // Params define parameters for Apply -// it's a parameters union set of all implements which implement Apply +// it's a parameters union set of all implements which implement Apply. type Params struct { RetryCount int FirstRetryDuration time.Duration @@ -45,7 +45,7 @@ type Params struct { IsRetryableFn func(int, error) bool } -// Strategy define different kind of retry strategy +// Strategy define different kind of retry strategy. type Strategy interface { // Apply define retry strategy @@ -61,8 +61,7 @@ type Strategy interface { } // FiniteRetryStrategy will retry `RetryCount` times when failed to operate DB. -type FiniteRetryStrategy struct { -} +type FiniteRetryStrategy struct{} // Apply for FiniteRetryStrategy, it wait `FirstRetryDuration` before it starts first retry, and then rest of retries wait time depends on BackoffStrategy. func (*FiniteRetryStrategy) Apply(ctx *tcontext.Context, params Params, diff --git a/pkg/retry/strategy_test.go b/pkg/retry/strategy_test.go index 1fa2d9c814..4fc41223f7 100644 --- a/pkg/retry/strategy_test.go +++ b/pkg/retry/strategy_test.go @@ -31,8 +31,7 @@ func TestSuite(t *testing.T) { var _ = Suite(&testStrategySuite{}) -type testStrategySuite struct { -} +type testStrategySuite struct{} func (t *testStrategySuite) TestFiniteRetryStrategy(c *C) { strategy := &FiniteRetryStrategy{} @@ -95,5 +94,4 @@ func (t *testStrategySuite) TestFiniteRetryStrategy(c *C) { c.Assert(ret.(string), Equals, retValue) c.Assert(opCount, Equals, 0) c.Assert(err, IsNil) - } diff --git a/pkg/schema/tracker.go b/pkg/schema/tracker.go index 1551313b25..ecc73597fa 100644 --- a/pkg/schema/tracker.go +++ b/pkg/schema/tracker.go @@ -44,7 +44,7 @@ const ( var ( // don't read clustered index variable from downstream because it may changed during syncing - // we always using OFF tidb_enable_clustered_index unless user set it in config + // we always using OFF tidb_enable_clustered_index unless user set it in config. downstreamVars = []string{"sql_mode", "tidb_skip_utf8_check"} defaultGlobalVars = map[string]string{"tidb_enable_clustered_index": "OFF"} ) @@ -58,7 +58,7 @@ type Tracker struct { // NewTracker creates a new tracker. `sessionCfg` will be set as tracker's session variables if specified, or retrieve // some variable from downstream TiDB using `tidbConn`. -// NOTE **sessionCfg is a reference to caller** +// NOTE **sessionCfg is a reference to caller**. func NewTracker(ctx context.Context, task string, sessionCfg map[string]string, tidbConn *conn.BaseConn) (*Tracker, error) { // NOTE: tidb uses a **global** config so can't isolate tracker's config from each other. If that isolation is needed, // we might SetGlobalConfig before every call to tracker, or use some patch like https://github.com/bouk/monkey @@ -89,6 +89,7 @@ func NewTracker(ctx context.Context, task string, sessionCfg map[string]string, } sessionCfg[k] = value } + // nolint:sqlclosecheck if err2 = rows.Close(); err2 != nil { return nil, err2 } @@ -177,6 +178,7 @@ func (tr *Tracker) GetCreateTable(ctx context.Context, db, table string) (string } else if len(rs) != 1 { return "", nil // this should not happen. } + // nolint:errcheck defer rs[0].Close() req := rs[0].NewChunk() @@ -256,7 +258,7 @@ func (tr *Tracker) Reset() error { return nil } -// Close close a tracker +// Close close a tracker. func (tr *Tracker) Close() error { tr.se.Close() tr.dom.Close() diff --git a/pkg/schema/tracker_test.go b/pkg/schema/tracker_test.go index ce0a993f24..a3dc1db629 100644 --- a/pkg/schema/tracker_test.go +++ b/pkg/schema/tracker_test.go @@ -35,9 +35,7 @@ func Test(t *testing.T) { var _ = Suite(&trackerSuite{}) -var ( - defaultTestSessionCfg = map[string]string{"sql_mode": "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"} -) +var defaultTestSessionCfg = map[string]string{"sql_mode": "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"} type trackerSuite struct { baseConn *conn.BaseConn @@ -227,7 +225,6 @@ func (s *trackerSuite) TestDDL(c *C) { cts, err = tracker.GetCreateTable(context.Background(), "testdb", "foo") c.Assert(err, IsNil) c.Assert(cts, Equals, "CREATE TABLE `foo` ( `a` varchar(255) NOT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`) /*T![clustered_index] NONCLUSTERED */) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin") - } func (s *trackerSuite) TestGetSingleColumnIndices(c *C) { diff --git a/pkg/shardddl/optimism/column.go b/pkg/shardddl/optimism/column.go index 86a1d38c89..ef2c7fa619 100644 --- a/pkg/shardddl/optimism/column.go +++ b/pkg/shardddl/optimism/column.go @@ -23,7 +23,7 @@ import ( ) // GetAllDroppedColumns gets the all partially dropped columns. -// return lockID -> column-name -> source-id -> upstream-schema-name -> upstream-table-name +// return lockID -> column-name -> source-id -> upstream-schema-name -> upstream-table-name. func GetAllDroppedColumns(cli *clientv3.Client) (map[string]map[string]map[string]map[string]map[string]DropColumnStage, int64, error) { var done DropColumnStage colm := make(map[string]map[string]map[string]map[string]map[string]DropColumnStage) diff --git a/pkg/shardddl/optimism/column_test.go b/pkg/shardddl/optimism/column_test.go index e6ea7cbe1b..6b2aafe842 100644 --- a/pkg/shardddl/optimism/column_test.go +++ b/pkg/shardddl/optimism/column_test.go @@ -56,9 +56,13 @@ func (t *testColumn) TestColumnETCD(c *C) { expectedColm := map[string]map[string]map[string]map[string]map[string]DropColumnStage{ lockID: { "a": {source1: {upSchema1: {upTable1: DropNotDone}}}, - "b": {source1: {upSchema1: {upTable1: DropNotDone}, - upSchema2: {upTable2: DropNotDone}}, - source2: {upSchema1: {upTable1: DropNotDone}}}, + "b": { + source1: { + upSchema1: {upTable1: DropNotDone}, + upSchema2: {upTable2: DropNotDone}, + }, + source2: {upSchema1: {upTable1: DropNotDone}}, + }, }, } colm, rev5, err := GetAllDroppedColumns(etcdTestCli) diff --git a/pkg/shardddl/optimism/info.go b/pkg/shardddl/optimism/info.go index f671a5faa8..bf2860c105 100644 --- a/pkg/shardddl/optimism/info.go +++ b/pkg/shardddl/optimism/info.go @@ -82,7 +82,7 @@ type LogInfo struct { // NewInfo creates a new Info instance. func NewInfo(task, source, upSchema, upTable, downSchema, downTable string, - DDLs []string, tableInfoBefore *model.TableInfo, tableInfosAfter []*model.TableInfo) Info { + ddls []string, tableInfoBefore *model.TableInfo, tableInfosAfter []*model.TableInfo) Info { return Info{ Task: task, Source: source, @@ -90,7 +90,7 @@ func NewInfo(task, source, upSchema, upTable, downSchema, downTable string, UpTable: upTable, DownSchema: downSchema, DownTable: downTable, - DDLs: DDLs, + DDLs: ddls, TableInfoBefore: tableInfoBefore, TableInfosAfter: tableInfosAfter, } @@ -102,7 +102,7 @@ func (i Info) String() string { return s } -// ShortString returns short string of Info +// ShortString returns short string of Info. func (i *Info) ShortString() string { logInfo := LogInfo{ Task: i.Task, diff --git a/pkg/shardddl/optimism/info_test.go b/pkg/shardddl/optimism/info_test.go index 2288132ee8..505e3f50ca 100644 --- a/pkg/shardddl/optimism/info_test.go +++ b/pkg/shardddl/optimism/info_test.go @@ -30,9 +30,7 @@ import ( "go.etcd.io/etcd/integration" ) -var ( - etcdTestCli *clientv3.Client -) +var etcdTestCli *clientv3.Client func TestInfo(t *testing.T) { mockCluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) @@ -102,7 +100,7 @@ func (t *testForEtcd) TestInfoEtcd(c *C) { downTable = "bar" p = parser.New() se = mock.NewContext() - tblID int64 = 111 + tblID int64 = 222 tblI1 = createTableInfo(c, p, se, tblID, `CREATE TABLE bar (id INT PRIMARY KEY)`) tblI2 = createTableInfo(c, p, se, tblID, `CREATE TABLE bar (id INT PRIMARY KEY, c1 INT)`) tblI3 = createTableInfo(c, p, se, tblID, `CREATE TABLE bar (id INT PRIMARY KEY, c1 INT, c2 INT)`) diff --git a/pkg/shardddl/optimism/keeper.go b/pkg/shardddl/optimism/keeper.go index ae1f47dccb..5521e8b0e8 100644 --- a/pkg/shardddl/optimism/keeper.go +++ b/pkg/shardddl/optimism/keeper.go @@ -38,7 +38,7 @@ func NewLockKeeper() *LockKeeper { } } -// RebuildLocksAndTables rebuild the locks and tables +// RebuildLocksAndTables rebuild the locks and tables. func (lk *LockKeeper) RebuildLocksAndTables( cli *clientv3.Client, ifm map[string]map[string]map[string]map[string]Info, diff --git a/pkg/shardddl/optimism/keeper_test.go b/pkg/shardddl/optimism/keeper_test.go index ca1b15d727..403a6b7223 100644 --- a/pkg/shardddl/optimism/keeper_test.go +++ b/pkg/shardddl/optimism/keeper_test.go @@ -17,12 +17,13 @@ import ( "testing" . "github.com/pingcap/check" - "github.com/pingcap/dm/pkg/utils" "github.com/pingcap/parser" "github.com/pingcap/parser/model" "github.com/pingcap/tidb-tools/pkg/schemacmp" "github.com/pingcap/tidb/util/mock" "go.etcd.io/etcd/integration" + + "github.com/pingcap/dm/pkg/utils" ) type testKeeper struct{} diff --git a/pkg/shardddl/optimism/lock.go b/pkg/shardddl/optimism/lock.go index ebeea2f39f..9c5682948e 100644 --- a/pkg/shardddl/optimism/lock.go +++ b/pkg/shardddl/optimism/lock.go @@ -32,11 +32,11 @@ import ( type DropColumnStage int const ( - // DropNotDone represents master haven't received done for the col + // DropNotDone represents master haven't received done for the col. DropNotDone DropColumnStage = iota - // DropPartiallyDone represents master receive done for the col + // DropPartiallyDone represents master receive done for the col. DropPartiallyDone - // DropDone represents master receive done and ddl for the col(executed in downstream) + // DropDone represents master receive done and ddl for the col(executed in downstream). DropDone ) @@ -79,10 +79,10 @@ type Lock struct { // NewLock creates a new Lock instance. // NOTE: we MUST give the initial table info when creating the lock now. -func NewLock(cli *clientv3.Client, ID, task, downSchema, downTable string, joined schemacmp.Table, tts []TargetTable) *Lock { +func NewLock(cli *clientv3.Client, id, task, downSchema, downTable string, joined schemacmp.Table, tts []TargetTable) *Lock { l := &Lock{ cli: cli, - ID: ID, + ID: id, Task: task, DownSchema: downSchema, DownTable: downTable, @@ -476,8 +476,7 @@ func (l *Lock) IsResolved() bool { defer l.mu.RUnlock() // whether all tables have the same schema. - _, remain := l.syncStatus() - if remain != 0 { + if _, remain := l.syncStatus(); remain != 0 { return false } @@ -569,7 +568,7 @@ func (l *Lock) GetVersion(source string, schema string, table string) int64 { return l.versions[source][schema][table] } -// IsDroppedColumn checks whether this column is a partially dropped column for this lock +// IsDroppedColumn checks whether this column is a partially dropped column for this lock. func (l *Lock) IsDroppedColumn(source, upSchema, upTable, col string) bool { if _, ok := l.columns[col]; !ok { return false @@ -586,7 +585,7 @@ func (l *Lock) IsDroppedColumn(source, upSchema, upTable, col string) bool { return true } -// AddDroppedColumn adds a dropped column name in both etcd and lock's column map +// AddDroppedColumn adds a dropped column name in both etcd and lock's column map. func (l *Lock) AddDroppedColumn(info Info, col string) error { source, upSchema, upTable := info.Source, info.UpSchema, info.UpTable if l.IsDroppedColumn(source, upSchema, upTable, col) { @@ -686,7 +685,7 @@ func (l *Lock) DeleteColumnsByOp(op Operation) error { return nil } -// AddDifferentFieldLenColumns checks whether dm adds columns with different field lengths +// AddDifferentFieldLenColumns checks whether dm adds columns with different field lengths. func AddDifferentFieldLenColumns(lockID, ddl string, oldJoined, newJoined schemacmp.Table) (string, error) { col, err := GetColumnName(lockID, ddl, ast.AlterTableAddColumns) if err != nil { @@ -706,7 +705,7 @@ func AddDifferentFieldLenColumns(lockID, ddl string, oldJoined, newJoined schema return col, nil } -// GetColumnName checks whether dm adds/drops a column, and return this column's name +// GetColumnName checks whether dm adds/drops a column, and return this column's name. func GetColumnName(lockID, ddl string, tp ast.AlterTableType) (string, error) { if stmt, err := parser.New().ParseOneStmt(ddl, "", ""); err != nil { return "", terror.ErrShardDDLOptimismTrySyncFail.Delegate( diff --git a/pkg/shardddl/optimism/lock_test.go b/pkg/shardddl/optimism/lock_test.go index 37dd768676..a231344175 100644 --- a/pkg/shardddl/optimism/lock_test.go +++ b/pkg/shardddl/optimism/lock_test.go @@ -361,6 +361,7 @@ func (t *testLock) TestLockTrySyncNormal(c *C) { } func (t *testLock) TestLockTrySyncIndex(c *C) { + // nolint:dupl var ( ID = "test_lock_try_sync_index-`foo`.`bar`" task = "test_lock_try_sync_index" @@ -443,6 +444,7 @@ func (t *testLock) TestLockTrySyncIndex(c *C) { } func (t *testLock) TestLockTrySyncNullNotNull(c *C) { + // nolint:dupl var ( ID = "test_lock_try_sync_null_not_null-`foo`.`bar`" task = "test_lock_try_sync_null_not_null" @@ -1778,15 +1780,15 @@ func (t *testLock) TestAddNotFullyDroppedColumns(c *C) { } func (t *testLock) trySyncForAllTablesLarger(c *C, l *Lock, - DDLs []string, tableInfoBefore *model.TableInfo, tis []*model.TableInfo, tts []TargetTable, vers map[string]map[string]map[string]int64) { + ddls []string, tableInfoBefore *model.TableInfo, tis []*model.TableInfo, tts []TargetTable, vers map[string]map[string]map[string]int64) { for source, schemaTables := range l.Ready() { for schema, tables := range schemaTables { for table := range tables { - info := newInfoWithVersion(l.Task, source, schema, table, l.DownSchema, l.DownTable, DDLs, tableInfoBefore, tis, vers) + info := newInfoWithVersion(l.Task, source, schema, table, l.DownSchema, l.DownTable, ddls, tableInfoBefore, tis, vers) DDLs2, cols, err := l.TrySync(info, tts) c.Assert(err, IsNil) c.Assert(cols, DeepEquals, []string{}) - c.Assert(DDLs2, DeepEquals, DDLs) + c.Assert(DDLs2, DeepEquals, ddls) } } } @@ -1819,9 +1821,9 @@ func (t *testLock) checkLockNoDone(c *C, l *Lock) { } } -func newInfoWithVersion(task, source, upSchema, upTable, downSchema, downTable string, DDLs []string, tableInfoBefore *model.TableInfo, +func newInfoWithVersion(task, source, upSchema, upTable, downSchema, downTable string, ddls []string, tableInfoBefore *model.TableInfo, tableInfosAfter []*model.TableInfo, vers map[string]map[string]map[string]int64) Info { - info := NewInfo(task, source, upSchema, upTable, downSchema, downTable, DDLs, tableInfoBefore, tableInfosAfter) + info := NewInfo(task, source, upSchema, upTable, downSchema, downTable, ddls, tableInfoBefore, tableInfosAfter) vers[source][upSchema][upTable]++ info.Version = vers[source][upSchema][upTable] return info diff --git a/pkg/shardddl/optimism/operation.go b/pkg/shardddl/optimism/operation.go index 3b0990fb42..5a0b2353f9 100644 --- a/pkg/shardddl/optimism/operation.go +++ b/pkg/shardddl/optimism/operation.go @@ -62,15 +62,15 @@ type Operation struct { } // NewOperation creates a new Operation instance. -func NewOperation(ID, task, source, upSchema, upTable string, - DDLs []string, conflictStage ConflictStage, conflictMsg string, done bool, cols []string) Operation { +func NewOperation(id, task, source, upSchema, upTable string, + ddls []string, conflictStage ConflictStage, conflictMsg string, done bool, cols []string) Operation { return Operation{ - ID: ID, + ID: id, Task: task, Source: source, UpSchema: upSchema, UpTable: upTable, - DDLs: DDLs, + DDLs: ddls, ConflictStage: conflictStage, ConflictMsg: conflictMsg, Done: done, @@ -194,7 +194,6 @@ func GetInfosOperationsByTask(cli *clientv3.Client, task string) ([]Info, []Oper respTxn, _, err := etcdutil.DoOpsInOneTxnWithRetry(cli, clientv3.OpGet(common.ShardDDLOptimismInfoKeyAdapter.Encode(task), clientv3.WithPrefix()), clientv3.OpGet(common.ShardDDLOptimismOperationKeyAdapter.Encode(task), clientv3.WithPrefix())) - if err != nil { return nil, nil, 0, err } diff --git a/pkg/shardddl/pessimism/info.go b/pkg/shardddl/pessimism/info.go index e9af7de715..d1a4e162bc 100644 --- a/pkg/shardddl/pessimism/info.go +++ b/pkg/shardddl/pessimism/info.go @@ -38,13 +38,13 @@ type Info struct { } // NewInfo creates a new Info instance. -func NewInfo(task, source, schema, table string, DDLs []string) Info { +func NewInfo(task, source, schema, table string, ddls []string) Info { return Info{ Task: task, Source: source, Schema: schema, Table: table, - DDLs: DDLs, + DDLs: ddls, } } @@ -118,12 +118,13 @@ func PutInfoIfOpNotDone(cli *clientv3.Client, info Info) (rev int64, putted bool opsResp := resp.Responses[0].GetResponseRange() opBefore, err := operationFromJSON(string(opsResp.Kvs[0].Value)) - if err != nil { + switch { + case err != nil: return 0, false, err - } else if opBefore.Done { + case opBefore.Done: // the operation with `done` exist before, abort the PUT. return rev, false, nil - } else if utils.CompareShardingDDLs(opBefore.DDLs, info.DDLs) { //nolint:staticcheck + case utils.CompareShardingDDLs(opBefore.DDLs, info.DDLs): // TODO: try to handle put the same `done` DDL later. } diff --git a/pkg/shardddl/pessimism/info_test.go b/pkg/shardddl/pessimism/info_test.go index e034a4acc4..c55f706ee9 100644 --- a/pkg/shardddl/pessimism/info_test.go +++ b/pkg/shardddl/pessimism/info_test.go @@ -29,9 +29,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -var ( - etcdTestCli *clientv3.Client -) +var etcdTestCli *clientv3.Client func TestInfo(t *testing.T) { mockCluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) diff --git a/pkg/shardddl/pessimism/lock.go b/pkg/shardddl/pessimism/lock.go index 869971ac2a..034dde731f 100644 --- a/pkg/shardddl/pessimism/lock.go +++ b/pkg/shardddl/pessimism/lock.go @@ -42,12 +42,12 @@ type Lock struct { } // NewLock creates a new Lock instance. -func NewLock(ID, task, owner string, DDLs, sources []string) *Lock { +func NewLock(id, task, owner string, ddls, sources []string) *Lock { l := &Lock{ - ID: ID, + ID: id, Task: task, Owner: owner, - DDLs: DDLs, + DDLs: ddls, remain: len(sources), ready: make(map[string]bool), done: make(map[string]bool), @@ -64,13 +64,13 @@ func NewLock(ID, task, owner string, DDLs, sources []string) *Lock { // TrySync tries to sync the lock, does decrease on remain, re-entrant. // new upstream sources may join when the DDL lock is in syncing, // so we need to merge these new sources. -func (l *Lock) TrySync(caller string, DDLs, sources []string) (bool, int, error) { +func (l *Lock) TrySync(caller string, ddls, sources []string) (bool, int, error) { l.mu.Lock() defer l.mu.Unlock() // check DDL statement first. - if !utils.CompareShardingDDLs(DDLs, l.DDLs) { - return l.remain <= 0, l.remain, terror.ErrMasterShardingDDLDiff.Generate(l.DDLs, DDLs) + if !utils.CompareShardingDDLs(ddls, l.DDLs) { + return l.remain <= 0, l.remain, terror.ErrMasterShardingDDLDiff.Generate(l.DDLs, ddls) } // try to merge any newly joined sources. diff --git a/pkg/shardddl/pessimism/operation.go b/pkg/shardddl/pessimism/operation.go index 1b226b788b..8520e345ca 100644 --- a/pkg/shardddl/pessimism/operation.go +++ b/pkg/shardddl/pessimism/operation.go @@ -42,12 +42,12 @@ type Operation struct { } // NewOperation creates a new Operation instance. -func NewOperation(ID, task, source string, DDLs []string, exec, done bool) Operation { +func NewOperation(id, task, source string, ddls []string, exec, done bool) Operation { return Operation{ - ID: ID, + ID: id, Task: task, Source: source, - DDLs: DDLs, + DDLs: ddls, Exec: exec, Done: done, } @@ -174,7 +174,6 @@ func GetInfosOperationsByTask(cli *clientv3.Client, task string) ([]Info, []Oper respTxn, _, err := etcdutil.DoOpsInOneTxnWithRetry(cli, clientv3.OpGet(common.ShardDDLPessimismInfoKeyAdapter.Encode(task), clientv3.WithPrefix()), clientv3.OpGet(common.ShardDDLPessimismOperationKeyAdapter.Encode(task), clientv3.WithPrefix())) - if err != nil { return nil, nil, 0, err } diff --git a/pkg/shardddl/pessimism/operation_test.go b/pkg/shardddl/pessimism/operation_test.go index 1f22497a31..1e37381d92 100644 --- a/pkg/shardddl/pessimism/operation_test.go +++ b/pkg/shardddl/pessimism/operation_test.go @@ -18,6 +18,7 @@ import ( "time" . "github.com/pingcap/check" + "github.com/pingcap/dm/pkg/utils" ) diff --git a/pkg/streamer/file.go b/pkg/streamer/file.go index 4860dd3a17..e23c46cc2f 100644 --- a/pkg/streamer/file.go +++ b/pkg/streamer/file.go @@ -31,10 +31,10 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// FileCmp is a compare condition used when collecting binlog files +// FileCmp is a compare condition used when collecting binlog files. type FileCmp uint8 -// FileCmpLess represents a < FileCmp condition, others are similar +// FileCmpLess represents a < FileCmp condition, others are similar. const ( FileCmpLess FileCmp = iota + 1 FileCmpLessEqual @@ -43,13 +43,13 @@ const ( FileCmpBigger ) -// SwitchPath represents next binlog file path which should be switched +// SwitchPath represents next binlog file path which should be switched. type SwitchPath struct { nextUUID string nextBinlogName string } -// CollectAllBinlogFiles collects all valid binlog files in dir +// CollectAllBinlogFiles collects all valid binlog files in dir. func CollectAllBinlogFiles(dir string) ([]string, error) { if dir == "" { return nil, terror.ErrEmptyRelayDir.Generate() @@ -75,7 +75,7 @@ func CollectAllBinlogFiles(dir string) ([]string, error) { return ret, nil } -// CollectBinlogFilesCmp collects valid binlog files with a compare condition +// CollectBinlogFilesCmp collects valid binlog files with a compare condition. func CollectBinlogFilesCmp(dir, baseFile string, cmp FileCmp) ([]string, error) { if dir == "" { return nil, terror.ErrEmptyRelayDir.Generate() @@ -129,7 +129,7 @@ func CollectBinlogFilesCmp(dir, baseFile string, cmp FileCmp) ([]string, error) return results, nil } -// getFirstBinlogName gets the first binlog file in relay sub directory +// getFirstBinlogName gets the first binlog file in relay sub directory. func getFirstBinlogName(baseDir, uuid string) (string, error) { subDir := filepath.Join(baseDir, uuid) files, err := readDir(subDir) @@ -152,7 +152,7 @@ func getFirstBinlogName(baseDir, uuid string) (string, error) { return "", terror.ErrBinlogFilesNotFound.Generate(subDir) } -// readDir reads and returns all file(sorted asc) and dir names from directory f +// readDir reads and returns all file(sorted asc) and dir names from directory f. func readDir(dirpath string) ([]string, error) { dir, err := os.Open(dirpath) if err != nil { @@ -182,12 +182,13 @@ func fileSizeUpdated(path string, latestSize int64) (int, error) { return 0, terror.ErrGetRelayLogStat.Delegate(err, path) } currSize := fi.Size() - if currSize == latestSize { + switch { + case currSize == latestSize: return 0, nil - } else if currSize > latestSize { + case currSize > latestSize: log.L().Debug("size of relay log file has been changed", zap.String("file", path), zap.Int64("old size", latestSize), zap.Int64("size", currSize)) return 1, nil - } else { + default: log.L().Error("size of relay log file has been changed", zap.String("file", path), zap.Int64("old size", latestSize), zap.Int64("size", currSize)) return -1, nil } @@ -291,15 +292,16 @@ func relaySubDirUpdated(ctx context.Context, watcherInterval time.Duration, dir // check the latest relay log file whether updated when adding watching and collecting newer cmp, err := fileSizeUpdated(latestFilePath, latestFileSize) - if err != nil { + switch { + case err != nil: return - } else if cmp < 0 { + case cmp < 0: err = terror.ErrRelayLogFileSizeSmaller.Generate(latestFilePath) return - } else if cmp > 0 { + case cmp > 0: updatePathCh <- latestFilePath return - } else if len(newerFiles) > 0 { + case len(newerFiles) > 0: // check whether newer relay log file exists nextFilePath := filepath.Join(dir, newerFiles[0]) log.L().Info("newer relay log file is already generated, start parse from it", zap.String("new file", nextFilePath)) @@ -316,8 +318,8 @@ func relaySubDirUpdated(ctx context.Context, watcherInterval time.Duration, dir updatePathCh <- res.updatePath } -// needSwitchSubDir checks whether the reader need to switch to next relay sub directory -func needSwitchSubDir(ctx context.Context, relayDir, currentUUID, latestFilePath string, latestFileSize int64, switchCh chan SwitchPath, errCh chan error) { +// needSwitchSubDir checks whether the reader need to switch to next relay sub directory. +func needSwitchSubDir(ctx context.Context, relayDir, currentUUID string, switchCh chan SwitchPath, errCh chan error) { var ( err error nextUUID string diff --git a/pkg/streamer/file_test.go b/pkg/streamer/file_test.go index e92ea2aae5..278cd1d398 100644 --- a/pkg/streamer/file_test.go +++ b/pkg/streamer/file_test.go @@ -33,8 +33,7 @@ import ( var _ = Suite(&testFileSuite{}) -type testFileSuite struct { -} +type testFileSuite struct{} func (t *testFileSuite) TestCollectBinlogFiles(c *C) { var ( @@ -62,7 +61,7 @@ func (t *testFileSuite) TestCollectBinlogFiles(c *C) { // create all valid binlog files for _, fn := range valid { - err = ioutil.WriteFile(filepath.Join(dir, fn), nil, 0600) + err = ioutil.WriteFile(filepath.Join(dir, fn), nil, 0o600) c.Assert(err, IsNil) } files, err = CollectAllBinlogFiles(dir) @@ -71,7 +70,7 @@ func (t *testFileSuite) TestCollectBinlogFiles(c *C) { // create some invalid binlog files for _, fn := range invalid { - err = ioutil.WriteFile(filepath.Join(dir, fn), nil, 0600) + err = ioutil.WriteFile(filepath.Join(dir, fn), nil, 0o600) c.Assert(err, IsNil) } files, err = CollectAllBinlogFiles(dir) @@ -80,7 +79,7 @@ func (t *testFileSuite) TestCollectBinlogFiles(c *C) { // create some invalid meta files for _, fn := range meta { - err = ioutil.WriteFile(filepath.Join(dir, fn), nil, 0600) + err = ioutil.WriteFile(filepath.Join(dir, fn), nil, 0o600) c.Assert(err, IsNil) } files, err = CollectAllBinlogFiles(dir) @@ -150,7 +149,7 @@ func (t *testFileSuite) TestCollectBinlogFilesCmp(c *C) { // create a meta file filename := filepath.Join(dir, utils.MetaFilename) - err = ioutil.WriteFile(filename, nil, 0600) + err = ioutil.WriteFile(filename, nil, 0o600) c.Assert(err, IsNil) // invalid base filename, is a meta filename @@ -161,7 +160,7 @@ func (t *testFileSuite) TestCollectBinlogFilesCmp(c *C) { // create some binlog files for _, f := range binlogFiles { filename = filepath.Join(dir, f) - err = ioutil.WriteFile(filename, nil, 0600) + err = ioutil.WriteFile(filename, nil, 0o600) c.Assert(err, IsNil) } @@ -192,7 +191,7 @@ func (t *testFileSuite) TestCollectBinlogFilesCmp(c *C) { // add a basename mismatch binlog file filename = filepath.Join(dir, "bin-mysql.100000") - err = ioutil.WriteFile(filename, nil, 0600) + err = ioutil.WriteFile(filename, nil, 0o600) c.Assert(err, IsNil) // test again, should ignore it @@ -224,7 +223,7 @@ func (t *testFileSuite) TestGetFirstBinlogName(c *C) { c.Assert(name, Equals, "") // empty directory - err = os.MkdirAll(subDir, 0700) + err = os.MkdirAll(subDir, 0o700) c.Assert(err, IsNil) name, err = getFirstBinlogName(baseDir, uuid) c.Assert(err, ErrorMatches, ".*not found.*") @@ -232,7 +231,7 @@ func (t *testFileSuite) TestGetFirstBinlogName(c *C) { // has file, but not a valid binlog file filename := "invalid.bin" - err = ioutil.WriteFile(filepath.Join(subDir, filename), nil, 0600) + err = ioutil.WriteFile(filepath.Join(subDir, filename), nil, 0o600) c.Assert(err, IsNil) _, err = getFirstBinlogName(baseDir, uuid) c.Assert(err, ErrorMatches, ".*not valid.*") @@ -241,7 +240,7 @@ func (t *testFileSuite) TestGetFirstBinlogName(c *C) { // has a valid binlog file filename = "z-mysql-bin.000002" // z prefix, make it become not the _first_ if possible. - err = ioutil.WriteFile(filepath.Join(subDir, filename), nil, 0600) + err = ioutil.WriteFile(filepath.Join(subDir, filename), nil, 0o600) c.Assert(err, IsNil) name, err = getFirstBinlogName(baseDir, uuid) c.Assert(err, IsNil) @@ -249,14 +248,14 @@ func (t *testFileSuite) TestGetFirstBinlogName(c *C) { // has one more earlier binlog file filename = "z-mysql-bin.000001" - err = ioutil.WriteFile(filepath.Join(subDir, filename), nil, 0600) + err = ioutil.WriteFile(filepath.Join(subDir, filename), nil, 0o600) c.Assert(err, IsNil) name, err = getFirstBinlogName(baseDir, uuid) c.Assert(err, IsNil) c.Assert(name, Equals, filename) // has a meta file - err = ioutil.WriteFile(filepath.Join(subDir, utils.MetaFilename), nil, 0600) + err = ioutil.WriteFile(filepath.Join(subDir, utils.MetaFilename), nil, 0o600) c.Assert(err, IsNil) name, err = getFirstBinlogName(baseDir, uuid) c.Assert(err, IsNil) @@ -277,7 +276,7 @@ func (t *testFileSuite) TestFileSizeUpdated(c *C) { c.Assert(cmp, Equals, 0) // create and write the file - err = ioutil.WriteFile(filePath, data, 0600) + err = ioutil.WriteFile(filePath, data, 0o600) c.Assert(err, IsNil) // equal @@ -337,7 +336,7 @@ func (t *testUtilSuite) TestRelaySubDirUpdated(c *C) { c.Assert(err, ErrorMatches, ".*not found.*") // create the first relay file - err = ioutil.WriteFile(relayPaths[0], nil, 0600) + err = ioutil.WriteFile(relayPaths[0], nil, 0o600) c.Assert(err, IsNil) // c. latest file path not exist @@ -348,7 +347,7 @@ func (t *testUtilSuite) TestRelaySubDirUpdated(c *C) { c.Assert(err, ErrorMatches, ".*(no such file or directory|The system cannot find the file specified).*") // 1. file increased when adding watching - err = ioutil.WriteFile(relayPaths[0], data, 0600) + err = ioutil.WriteFile(relayPaths[0], data, 0o600) c.Assert(err, IsNil) var wg sync.WaitGroup wg.Add(1) @@ -363,7 +362,7 @@ func (t *testUtilSuite) TestRelaySubDirUpdated(c *C) { wg.Wait() // 2. file decreased when adding watching - err = ioutil.WriteFile(relayPaths[0], nil, 0600) + err = ioutil.WriteFile(relayPaths[0], nil, 0o600) c.Assert(err, IsNil) wg.Add(1) go func() { @@ -377,7 +376,7 @@ func (t *testUtilSuite) TestRelaySubDirUpdated(c *C) { wg.Wait() // 3. new file created when adding watching - err = ioutil.WriteFile(relayPaths[1], nil, 0600) + err = ioutil.WriteFile(relayPaths[1], nil, 0o600) c.Assert(err, IsNil) wg.Add(1) go func() { @@ -403,7 +402,7 @@ func (t *testUtilSuite) TestRelaySubDirUpdated(c *C) { // wait watcher started, update the file time.Sleep(2 * watcherInterval) - err = ioutil.WriteFile(relayPaths[1], data, 0600) + err = ioutil.WriteFile(relayPaths[1], data, 0o600) c.Assert(err, IsNil) wg.Wait() @@ -420,7 +419,7 @@ func (t *testUtilSuite) TestRelaySubDirUpdated(c *C) { // wait watcher started, create a new file time.Sleep(2 * watcherInterval) - err = ioutil.WriteFile(relayPaths[2], data, 0600) + err = ioutil.WriteFile(relayPaths[2], data, 0o600) c.Assert(err, IsNil) wg.Wait() @@ -440,22 +439,22 @@ func (t *testUtilSuite) TestRelaySubDirUpdated(c *C) { // wait watcher started, create new directory time.Sleep(2 * watcherInterval) - err = os.MkdirAll(filepath.Join(subDir, "new-directory"), 0700) + err = os.MkdirAll(filepath.Join(subDir, "new-directory"), 0o700) c.Assert(err, IsNil) // wait again, create an invalid binlog file time.Sleep(2 * watcherInterval) - err = ioutil.WriteFile(filepath.Join(subDir, "invalid-binlog-filename"), data, 0600) + err = ioutil.WriteFile(filepath.Join(subDir, "invalid-binlog-filename"), data, 0o600) c.Assert(err, IsNil) // wait again, rename an older filename, seems watch can not handle `RENAME` operation well - //time.Sleep(2 * watcherInterval) - //err = os.Rename(relayPaths[0], relayPaths[3]) - //c.Assert(err, IsNil) + // time.Sleep(2 * watcherInterval) + // err = os.Rename(relayPaths[0], relayPaths[3]) + // c.Assert(err, IsNil) // wait again, update the file time.Sleep(2 * watcherInterval) - err = ioutil.WriteFile(relayPaths[2], data, 0600) + err = ioutil.WriteFile(relayPaths[2], data, 0o600) c.Assert(err, IsNil) wg.Wait() } @@ -468,12 +467,9 @@ func (t *testFileSuite) TestNeedSwitchSubDir(c *C) { "53ea0ed1-9bf8-11e6-8bea-64006a897c72.000002", "53ea0ed1-9bf8-11e6-8bea-64006a897c71.000003", } - currentUUID = UUIDs[len(UUIDs)-1] // no next UUID - latestFilePath string - latestFileSize int64 - data = []byte("binlog file data") - switchCh = make(chan SwitchPath, 1) - errCh = make(chan error, 1) + currentUUID = UUIDs[len(UUIDs)-1] // no next UUID + switchCh = make(chan SwitchPath, 1) + errCh = make(chan error, 1) ) ctx := context.Background() @@ -481,7 +477,7 @@ func (t *testFileSuite) TestNeedSwitchSubDir(c *C) { // invalid UUID in UUIDs, error UUIDs = append(UUIDs, "invalid.uuid") t.writeUUIDs(c, relayDir, UUIDs) - needSwitchSubDir(ctx, relayDir, currentUUID, latestFilePath, latestFileSize, switchCh, errCh) + needSwitchSubDir(ctx, relayDir, currentUUID, switchCh, errCh) c.Assert(len(errCh), Equals, 1) c.Assert(len(switchCh), Equals, 0) err := <-errCh @@ -493,37 +489,36 @@ func (t *testFileSuite) TestNeedSwitchSubDir(c *C) { // no next UUID, no need switch newCtx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - needSwitchSubDir(newCtx, relayDir, currentUUID, latestFilePath, latestFileSize, switchCh, errCh) + needSwitchSubDir(newCtx, relayDir, currentUUID, switchCh, errCh) c.Assert(len(errCh), Equals, 0) c.Assert(len(switchCh), Equals, 0) // no next sub directory currentUUID = UUIDs[0] - needSwitchSubDir(ctx, relayDir, currentUUID, latestFilePath, latestFileSize, switchCh, errCh) + needSwitchSubDir(ctx, relayDir, currentUUID, switchCh, errCh) c.Assert(len(errCh), Equals, 1) c.Assert(len(switchCh), Equals, 0) err = <-errCh c.Assert(err, ErrorMatches, fmt.Sprintf(".*%s.*(no such file or directory|The system cannot find the file specified).*", UUIDs[1])) // create next sub directory, block - err = os.Mkdir(filepath.Join(relayDir, UUIDs[1]), 0700) + err = os.Mkdir(filepath.Join(relayDir, UUIDs[1]), 0o700) c.Assert(err, IsNil) newCtx2, cancel2 := context.WithTimeout(ctx, 5*time.Second) defer cancel2() - needSwitchSubDir(newCtx2, relayDir, currentUUID, latestFilePath, latestFileSize, switchCh, errCh) + needSwitchSubDir(newCtx2, relayDir, currentUUID, switchCh, errCh) c.Assert(len(errCh), Equals, 0) c.Assert(len(switchCh), Equals, 0) // create a relay log file in the next sub directory nextBinlogPath := filepath.Join(relayDir, UUIDs[1], "mysql-bin.000001") - err = os.MkdirAll(filepath.Dir(nextBinlogPath), 0700) + err = os.MkdirAll(filepath.Dir(nextBinlogPath), 0o700) c.Assert(err, IsNil) - err = ioutil.WriteFile(nextBinlogPath, nil, 0600) + err = ioutil.WriteFile(nextBinlogPath, nil, 0o600) c.Assert(err, IsNil) // switch to the next - latestFileSize = int64(len(data)) - needSwitchSubDir(ctx, relayDir, currentUUID, latestFilePath, latestFileSize, switchCh, errCh) + needSwitchSubDir(ctx, relayDir, currentUUID, switchCh, errCh) c.Assert(len(errCh), Equals, 0) c.Assert(len(switchCh), Equals, 1) res := <-switchCh @@ -531,10 +526,11 @@ func (t *testFileSuite) TestNeedSwitchSubDir(c *C) { c.Assert(res.nextBinlogName, Equals, filepath.Base(nextBinlogPath)) } -func (t *testFileSuite) writeUUIDs(c *C, relayDir string, UUIDs []string) []byte { +// nolint:unparam +func (t *testFileSuite) writeUUIDs(c *C, relayDir string, uuids []string) []byte { indexPath := path.Join(relayDir, utils.UUIDIndexFilename) var buf bytes.Buffer - for _, uuid := range UUIDs { + for _, uuid := range uuids { _, err := buf.WriteString(uuid) c.Assert(err, IsNil) _, err = buf.WriteString("\n") @@ -542,7 +538,7 @@ func (t *testFileSuite) writeUUIDs(c *C, relayDir string, UUIDs []string) []byte } // write the index file - err := ioutil.WriteFile(indexPath, buf.Bytes(), 0600) + err := ioutil.WriteFile(indexPath, buf.Bytes(), 0o600) c.Assert(err, IsNil) return buf.Bytes() } diff --git a/pkg/streamer/hub.go b/pkg/streamer/hub.go index 994f270f40..ec68311f1f 100644 --- a/pkg/streamer/hub.go +++ b/pkg/streamer/hub.go @@ -28,7 +28,7 @@ var ( once sync.Once ) -// RelayLogInfo represents information for relay log +// RelayLogInfo represents information for relay log. type RelayLogInfo struct { TaskName string UUID string @@ -36,7 +36,7 @@ type RelayLogInfo struct { Filename string } -// Earlier checks whether this relay log file is earlier than the other +// Earlier checks whether this relay log file is earlier than the other. func (info *RelayLogInfo) Earlier(other *RelayLogInfo) bool { if info.UUIDSuffix < other.UUIDSuffix { return true @@ -46,12 +46,12 @@ func (info *RelayLogInfo) Earlier(other *RelayLogInfo) bool { return strings.Compare(info.Filename, other.Filename) < 0 } -// String implements Stringer.String +// String implements Stringer.String. func (info *RelayLogInfo) String() string { return filepath.Join(info.UUID, info.Filename) } -// relayLogInfoHub holds information for all active relay logs +// relayLogInfoHub holds information for all active relay logs. type relayLogInfoHub struct { mu sync.RWMutex logs map[string]RelayLogInfo @@ -107,12 +107,12 @@ func (h *relayLogInfoHub) earliest() (taskName string, earliest *RelayLogInfo) { return } -// ReaderHub holds information for all active Readers +// ReaderHub holds information for all active Readers. type ReaderHub struct { rlih *relayLogInfoHub } -// GetReaderHub gets singleton instance of ReaderHub +// GetReaderHub gets singleton instance of ReaderHub. func GetReaderHub() *ReaderHub { once.Do(func() { readerHub = &ReaderHub{ @@ -122,17 +122,17 @@ func GetReaderHub() *ReaderHub { return readerHub } -// UpdateActiveRelayLog updates active relay log for taskName +// UpdateActiveRelayLog updates active relay log for taskName. func (h *ReaderHub) UpdateActiveRelayLog(taskName, uuid, filename string) error { return h.rlih.update(taskName, uuid, filename) } -// RemoveActiveRelayLog removes active relay log for taskName +// RemoveActiveRelayLog removes active relay log for taskName. func (h *ReaderHub) RemoveActiveRelayLog(taskName string) { h.rlih.remove(taskName) } -// EarliestActiveRelayLog implements RelayOperator.EarliestActiveRelayLog +// EarliestActiveRelayLog implements RelayOperator.EarliestActiveRelayLog. func (h *ReaderHub) EarliestActiveRelayLog() *RelayLogInfo { _, rli := h.rlih.earliest() return rli diff --git a/pkg/streamer/hub_test.go b/pkg/streamer/hub_test.go index ab302914b7..c6c0bb619d 100644 --- a/pkg/streamer/hub_test.go +++ b/pkg/streamer/hub_test.go @@ -21,8 +21,7 @@ import ( var _ = Suite(&testHubSuite{}) -type testHubSuite struct { -} +type testHubSuite struct{} func (t *testHubSuite) TestRelayLogInfo(c *C) { rli1 := RelayLogInfo{} @@ -55,7 +54,7 @@ func (t *testHubSuite) TestRelayLogInfo(c *C) { } func (t *testHubSuite) TestRelayLogInfoHub(c *C) { - var rlih = newRelayLogInfoHub() + rlih := newRelayLogInfoHub() taskName, earliest := rlih.earliest() c.Assert(taskName, Equals, "") c.Assert(earliest, IsNil) diff --git a/pkg/streamer/reader.go b/pkg/streamer/reader.go index 3fce85cc1d..cb879b5099 100644 --- a/pkg/streamer/reader.go +++ b/pkg/streamer/reader.go @@ -39,7 +39,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// Meta represents binlog meta information in relay.meta +// Meta represents binlog meta information in relay.meta. type Meta struct { BinLogName string `toml:"binlog-name" json:"binlog-name"` BinLogPos uint32 `toml:"binlog-pos" json:"binlog-pos"` @@ -47,12 +47,10 @@ type Meta struct { UUID string `toml:"-" json:"-"` } -var ( - // polling interval for watcher - watcherInterval = 100 * time.Millisecond -) +// polling interval for watcher. +var watcherInterval = 100 * time.Millisecond -// BinlogReaderConfig is the configuration for BinlogReader +// BinlogReaderConfig is the configuration for BinlogReader. type BinlogReaderConfig struct { RelayDir string Timezone *time.Location @@ -79,7 +77,7 @@ type BinlogReader struct { prevGset, currGset mysql.GTIDSet } -// NewBinlogReader creates a new BinlogReader +// NewBinlogReader creates a new BinlogReader. func NewBinlogReader(logger log.Logger, cfg *BinlogReaderConfig) *BinlogReader { ctx, cancel := context.WithCancel(context.Background()) // only can be canceled in `Close` parser := replication.NewBinlogParser() @@ -101,7 +99,7 @@ func NewBinlogReader(logger log.Logger, cfg *BinlogReaderConfig) *BinlogReader { } } -// checkRelayPos will check whether the given relay pos is too big +// checkRelayPos will check whether the given relay pos is too big. func (r *BinlogReader) checkRelayPos(pos mysql.Position) error { currentUUID, _, realPos, err := binlog.ExtractPos(pos, r.uuids) if err != nil { @@ -120,7 +118,7 @@ func (r *BinlogReader) checkRelayPos(pos mysql.Position) error { return nil } -// IsGTIDCoverPreviousFiles check whether gset contains file's previous_gset +// IsGTIDCoverPreviousFiles check whether gset contains file's previous_gset. func (r *BinlogReader) IsGTIDCoverPreviousFiles(ctx context.Context, filePath string, gset mysql.GTIDSet) (bool, error) { fileReader := reader.NewFileReader(&reader.FileReaderConfig{Timezone: r.cfg.Timezone}) defer fileReader.Close() @@ -150,11 +148,12 @@ func (r *BinlogReader) IsGTIDCoverPreviousFiles(ctx context.Context, filePath st return false, err } - if e.Header.EventType == replication.PREVIOUS_GTIDS_EVENT { + switch { + case e.Header.EventType == replication.PREVIOUS_GTIDS_EVENT: gs, err = event.GTIDsFromPreviousGTIDsEvent(e) - } else if e.Header.EventType == replication.MARIADB_GTID_LIST_EVENT { + case e.Header.EventType == replication.MARIADB_GTID_LIST_EVENT: gs, err = event.GTIDsFromMariaDBGTIDListEvent(e) - } else { + default: continue } @@ -165,7 +164,7 @@ func (r *BinlogReader) IsGTIDCoverPreviousFiles(ctx context.Context, filePath st } } -// getPosByGTID gets file position by gtid, result should be (filename, 4) +// getPosByGTID gets file position by gtid, result should be (filename, 4). func (r *BinlogReader) getPosByGTID(gset mysql.GTIDSet) (*mysql.Position, error) { // start from newest uuid dir for i := len(r.uuids) - 1; i >= 0; i-- { @@ -249,7 +248,7 @@ func (r *BinlogReader) StartSyncByPos(pos mysql.Position) (Streamer, error) { return s, nil } -// StartSyncByGTID start sync by gtid +// StartSyncByGTID start sync by gtid. func (r *BinlogReader) StartSyncByGTID(gset mysql.GTIDSet) (Streamer, error) { r.tctx.L().Info("begin to sync binlog", zap.Stringer("GTID Set", gset)) r.usingGTID = true @@ -258,8 +257,7 @@ func (r *BinlogReader) StartSyncByGTID(gset mysql.GTIDSet) (Streamer, error) { return nil, terror.ErrReaderAlreadyRunning.Generate() } - err := r.updateUUIDs() - if err != nil { + if err := r.updateUUIDs(); err != nil { return nil, err } @@ -292,7 +290,7 @@ func (r *BinlogReader) StartSyncByGTID(gset mysql.GTIDSet) (Streamer, error) { return s, nil } -// parseRelay parses relay root directory, it support master-slave switch (switching to next sub directory) +// parseRelay parses relay root directory, it support master-slave switch (switching to next sub directory). func (r *BinlogReader) parseRelay(ctx context.Context, s *LocalStreamer, pos mysql.Position) error { var ( needSwitch bool @@ -333,15 +331,15 @@ func (r *BinlogReader) parseRelay(ctx context.Context, s *LocalStreamer, pos mys } } -// parseDirAsPossible parses relay sub directory as far as possible +// parseDirAsPossible parses relay sub directory as far as possible. func (r *BinlogReader) parseDirAsPossible(ctx context.Context, s *LocalStreamer, pos mysql.Position) (needSwitch bool, nextUUID string, nextBinlogName string, err error) { currentUUID, _, realPos, err := binlog.ExtractPos(pos, r.uuids) if err != nil { return false, "", "", terror.Annotatef(err, "parse relay dir with pos %v", pos) } - pos = realPos // use realPos to do syncing - var firstParse = true // the first parse time for the relay log file - var dir = path.Join(r.cfg.RelayDir, currentUUID) + pos = realPos // use realPos to do syncing + firstParse := true // the first parse time for the relay log file + dir := path.Join(r.cfg.RelayDir, currentUUID) r.tctx.L().Info("start to parse relay log files in sub directory", zap.String("directory", dir), zap.Stringer("position", pos)) for { @@ -396,11 +394,9 @@ func (r *BinlogReader) parseDirAsPossible(ctx context.Context, s *LocalStreamer, } } -// parseFileAsPossible parses single relay log file as far as possible +// parseFileAsPossible parses single relay log file as far as possible. func (r *BinlogReader) parseFileAsPossible(ctx context.Context, s *LocalStreamer, relayLogFile string, offset int64, relayLogDir string, firstParse bool, currentUUID string, possibleLast bool) (needSwitch bool, latestPos int64, nextUUID string, nextBinlogName string, err error) { - var ( - needReParse bool - ) + var needReParse bool latestPos = offset replaceWithHeartbeat := false r.tctx.L().Debug("start to parse relay log file", zap.String("file", relayLogFile), zap.Int64("position", latestPos), zap.String("directory", relayLogDir)) @@ -425,7 +421,7 @@ func (r *BinlogReader) parseFileAsPossible(ctx context.Context, s *LocalStreamer } // parseFile parses single relay log file from specified offset -// TODO: move all stateful variables into a class, such as r.fileParser +// TODO: move all stateful variables into a class, such as r.fileParser. func (r *BinlogReader) parseFile( ctx context.Context, s *LocalStreamer, @@ -578,10 +574,10 @@ func (r *BinlogReader) parseFile( }() wg.Add(1) - go func(latestPos int64) { + go func() { defer wg.Done() - needSwitchSubDir(newCtx, r.cfg.RelayDir, currentUUID, fullPath, latestPos, switchCh, switchErrCh) - }(latestPos) + needSwitchSubDir(newCtx, r.cfg.RelayDir, currentUUID, switchCh, switchErrCh) + }() wg.Add(1) go func(latestPos int64) { @@ -618,7 +614,7 @@ func (r *BinlogReader) parseFile( } } -// updateUUIDs re-parses UUID index file and updates UUID list +// updateUUIDs re-parses UUID index file and updates UUID list. func (r *BinlogReader) updateUUIDs() error { uuids, err := utils.ParseUUIDIndex(r.indexPath) if err != nil { @@ -640,7 +636,7 @@ func (r *BinlogReader) Close() { r.tctx.L().Info("binlog reader closed") } -// GetUUIDs returns binlog reader's uuids +// GetUUIDs returns binlog reader's uuids. func (r *BinlogReader) GetUUIDs() []string { uuids := make([]string, 0, len(r.uuids)) uuids = append(uuids, r.uuids...) @@ -654,7 +650,7 @@ func (r *BinlogReader) getCurrentGtidSet() mysql.GTIDSet { return r.currGset.Clone() } -// advanceCurrentGtidSet advance gtid set and return whether currGset not updated +// advanceCurrentGtidSet advance gtid set and return whether currGset not updated. func (r *BinlogReader) advanceCurrentGtidSet(gtid string) (bool, error) { if r.currGset == nil { r.currGset = r.prevGset.Clone() diff --git a/pkg/streamer/reader_test.go b/pkg/streamer/reader_test.go index 5000b60cf9..9b9842fb08 100644 --- a/pkg/streamer/reader_test.go +++ b/pkg/streamer/reader_test.go @@ -34,7 +34,6 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/errors" "github.com/pingcap/failpoint" - "github.com/siddontang/go-mysql/mysql" gmysql "github.com/siddontang/go-mysql/mysql" "github.com/siddontang/go-mysql/replication" @@ -61,7 +60,7 @@ func TestReader(t *testing.T) { func (t *testReaderSuite) SetUpSuite(c *C) { var err error t.lastPos = 0 - t.lastGTID, err = gtid.ParserGTID(mysql.MySQLFlavor, "ba8f633f-1f15-11eb-b1c7-0242ac110002:0") + t.lastGTID, err = gtid.ParserGTID(gmysql.MySQLFlavor, "ba8f633f-1f15-11eb-b1c7-0242ac110002:0") c.Assert(err, IsNil) c.Assert(failpoint.Enable("github.com/pingcap/dm/pkg/streamer/SetHeartbeatInterval", "return(10000)"), IsNil) } @@ -87,7 +86,7 @@ func (t *testReaderSuite) TestParseFileBase(c *C) { // no valid currentUUID provide, failed currentUUID := "invalid-current-uuid" relayDir := filepath.Join(baseDir, currentUUID) - cfg := &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg := &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r := NewBinlogReader(log.L(), cfg) needSwitch, needReParse, latestPos, nextUUID, nextBinlogName, replaceWithHeartbeat, err := r.parseFile( ctx, s, filename, offset, relayDir, firstParse, currentUUID, possibleLast, false) @@ -103,7 +102,7 @@ func (t *testReaderSuite) TestParseFileBase(c *C) { currentUUID = "b60868af-5a6f-11e9-9ea3-0242ac160006.000001" relayDir = filepath.Join(baseDir, currentUUID) fullPath := filepath.Join(relayDir, filename) - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) // relay log file not exists, failed @@ -118,9 +117,9 @@ func (t *testReaderSuite) TestParseFileBase(c *C) { c.Assert(replaceWithHeartbeat, Equals, false) // empty relay log file, failed, got EOF - err = os.MkdirAll(relayDir, 0700) + err = os.MkdirAll(relayDir, 0o700) c.Assert(err, IsNil) - f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0600) + f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0o600) c.Assert(err, IsNil) defer f.Close() needSwitch, needReParse, latestPos, nextUUID, nextBinlogName, replaceWithHeartbeat, err = r.parseFile( @@ -156,7 +155,7 @@ func (t *testReaderSuite) TestParseFileBase(c *C) { // try get events back, firstParse should have fake RotateEvent var fakeRotateEventCount int - var i = 0 + i := 0 for { ev, err2 := s.GetEvent(ctx) c.Assert(err2, IsNil) @@ -271,14 +270,14 @@ func (t *testReaderSuite) TestParseFileRelaySubDirUpdated(c *C) { fullPath = filepath.Join(relayDir, filename) nextPath = filepath.Join(relayDir, nextFilename) s = newLocalStreamer() - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) ) // create the current relay log file and write some events - err := os.MkdirAll(relayDir, 0700) + err := os.MkdirAll(relayDir, 0o700) c.Assert(err, IsNil) - f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0600) + f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0o600) c.Assert(err, IsNil) defer f.Close() _, err = f.Write(replication.BinLogFileHeader) @@ -331,7 +330,7 @@ func (t *testReaderSuite) TestParseFileRelaySubDirUpdated(c *C) { go func() { defer wg.Done() time.Sleep(500 * time.Millisecond) // wait parseFile started - err2 := ioutil.WriteFile(nextPath, replication.BinLogFileHeader, 0600) + err2 := ioutil.WriteFile(nextPath, replication.BinLogFileHeader, 0o600) c.Assert(err2, IsNil) }() ctx3, cancel3 := context.WithTimeout(context.Background(), parseFileTimeout) @@ -365,14 +364,14 @@ func (t *testReaderSuite) TestParseFileRelayNeedSwitchSubDir(c *C) { fullPath = filepath.Join(relayDir, filename) nextFullPath = filepath.Join(nextRelayDir, nextFilename) s = newLocalStreamer() - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) ) // create the current relay log file and write some events - err := os.MkdirAll(relayDir, 0700) + err := os.MkdirAll(relayDir, 0o700) c.Assert(err, IsNil) - f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0600) + f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0o600) c.Assert(err, IsNil) defer f.Close() _, err = f.Write(replication.BinLogFileHeader) @@ -401,9 +400,9 @@ func (t *testReaderSuite) TestParseFileRelayNeedSwitchSubDir(c *C) { // next sub dir exits, need to switch r.uuids = []string{currentUUID, switchedUUID} t.writeUUIDs(c, baseDir, r.uuids) - err = os.MkdirAll(nextRelayDir, 0700) + err = os.MkdirAll(nextRelayDir, 0o700) c.Assert(err, IsNil) - err = ioutil.WriteFile(nextFullPath, replication.BinLogFileHeader, 0600) + err = ioutil.WriteFile(nextFullPath, replication.BinLogFileHeader, 0o600) c.Assert(err, IsNil) // has relay log file in next sub directory, need to switch @@ -436,14 +435,14 @@ func (t *testReaderSuite) TestParseFileRelayWithIgnorableError(c *C) { relayDir = filepath.Join(baseDir, currentUUID) fullPath = filepath.Join(relayDir, filename) s = newLocalStreamer() - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) ) // create the current relay log file and write some events - err := os.MkdirAll(relayDir, 0700) + err := os.MkdirAll(relayDir, 0o700) c.Assert(err, IsNil) - f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0600) + f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0o600) c.Assert(err, IsNil) defer f.Close() @@ -486,7 +485,7 @@ func (t *testReaderSuite) TestParseFileRelayWithIgnorableError(c *C) { func (t *testReaderSuite) TestUpdateUUIDs(c *C) { var ( baseDir = c.MkDir() - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) ) c.Assert(r.uuids, HasLen, 0) @@ -502,7 +501,7 @@ func (t *testReaderSuite) TestUpdateUUIDs(c *C) { "b60868af-5a6f-11e9-9ea3-0242ac160007.000002", } uuidBytes := t.uuidListToBytes(c, UUIDs) - err = ioutil.WriteFile(r.indexPath, uuidBytes, 0600) + err = ioutil.WriteFile(r.indexPath, uuidBytes, 0o600) c.Assert(err, IsNil) err = r.updateUUIDs() @@ -521,7 +520,7 @@ func (t *testReaderSuite) TestStartSyncByPos(c *C) { "b60868af-5a6f-11e9-9ea3-0242ac160007.000002", "b60868af-5a6f-11e9-9ea3-0242ac160008.000003", } - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) startPos = gmysql.Position{Name: "test-mysql-bin|000001.000001"} // from the first relay log file in the first sub directory ) @@ -536,13 +535,13 @@ func (t *testReaderSuite) TestStartSyncByPos(c *C) { // create the index file uuidBytes := t.uuidListToBytes(c, UUIDs) - err = ioutil.WriteFile(r.indexPath, uuidBytes, 0600) + err = ioutil.WriteFile(r.indexPath, uuidBytes, 0o600) c.Assert(err, IsNil) // create sub directories for _, uuid := range UUIDs { subDir := filepath.Join(baseDir, uuid) - err = os.MkdirAll(subDir, 0700) + err = os.MkdirAll(subDir, 0o700) c.Assert(err, IsNil) } @@ -552,7 +551,7 @@ func (t *testReaderSuite) TestStartSyncByPos(c *C) { for i := 0; i < 3; i++ { for j := 1; j < i+2; j++ { filename := filepath.Join(baseDir, UUIDs[i], filenamePrefix+strconv.Itoa(j)) - err = ioutil.WriteFile(filename, eventsBuf.Bytes(), 0600) + err = ioutil.WriteFile(filename, eventsBuf.Bytes(), 0o600) c.Assert(err, IsNil) } } @@ -586,7 +585,7 @@ func (t *testReaderSuite) TestStartSyncByPos(c *C) { // 2. write more events to the last file lastFilename := filepath.Join(baseDir, UUIDs[2], filenamePrefix+strconv.Itoa(3)) extraEvents, _, _ := t.genBinlogEvents(c, lastPos, lastGTID) - lastF, err := os.OpenFile(lastFilename, os.O_WRONLY|os.O_APPEND, 0600) + lastF, err := os.OpenFile(lastFilename, os.O_WRONLY|os.O_APPEND, 0o600) c.Assert(err, IsNil) defer lastF.Close() for _, ev := range extraEvents { @@ -614,7 +613,7 @@ func (t *testReaderSuite) TestStartSyncByPos(c *C) { // 3. create new file in the last directory lastFilename = filepath.Join(baseDir, UUIDs[2], filenamePrefix+strconv.Itoa(4)) - err = ioutil.WriteFile(lastFilename, eventsBuf.Bytes(), 0600) + err = ioutil.WriteFile(lastFilename, eventsBuf.Bytes(), 0o600) c.Assert(err, IsNil) obtainExtraEvents2 := make([]*replication.BinlogEvent, 0, len(baseEvents)-1) @@ -644,11 +643,11 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { var ( baseDir = c.MkDir() events []*replication.BinlogEvent - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) lastPos uint32 lastGTID gtid.Set - previousGset, _ = gtid.ParserGTID(mysql.MySQLFlavor, "") + previousGset, _ = gtid.ParserGTID(gmysql.MySQLFlavor, "") ) type EventResult struct { @@ -738,7 +737,8 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { }, }, }, - }, { + }, + { "bcbf9d42-1f15-11eb-a41c-0242ac110003", "bcbf9d42-1f15-11eb-a41c-0242ac110003.000003", "bcbf9d42-1f15-11eb-a41c-0242ac110003:30", @@ -763,7 +763,7 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { // write index file uuidBytes := t.uuidListToBytes(c, r.uuids) - err := ioutil.WriteFile(r.indexPath, uuidBytes, 0600) + err := ioutil.WriteFile(r.indexPath, uuidBytes, 0o600) c.Assert(err, IsNil) var allEvents []*replication.BinlogEvent @@ -772,10 +772,10 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { // generate binlog file for _, subDir := range testCase { lastPos = 4 - lastGTID, err = gtid.ParserGTID(mysql.MySQLFlavor, subDir.gtidStr) + lastGTID, err = gtid.ParserGTID(gmysql.MySQLFlavor, subDir.gtidStr) c.Assert(err, IsNil) uuidDir := path.Join(baseDir, subDir.uuid) - err = os.MkdirAll(uuidDir, 0700) + err = os.MkdirAll(uuidDir, 0o700) c.Assert(err, IsNil) for _, fileEventResult := range subDir.fileEventResult { @@ -792,7 +792,7 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { allEvents = append(allEvents, events...) // write binlog file - f, err2 := os.OpenFile(path.Join(uuidDir, fileEventResult.filename), os.O_CREATE|os.O_WRONLY, 0600) + f, err2 := os.OpenFile(path.Join(uuidDir, fileEventResult.filename), os.O_CREATE|os.O_WRONLY, 0o600) c.Assert(err2, IsNil) _, err = f.Write(replication.BinLogFileHeader) c.Assert(err, IsNil) @@ -812,7 +812,7 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { } } - startGTID, err := gtid.ParserGTID(mysql.MySQLFlavor, "") + startGTID, err := gtid.ParserGTID(gmysql.MySQLFlavor, "") c.Assert(err, IsNil) s, err := r.StartSyncByGTID(startGTID.Origin().Clone()) c.Assert(err, IsNil) @@ -833,7 +833,7 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { } } - preGset, err := mysql.ParseGTIDSet(mysql.MySQLFlavor, "") + preGset, err := gmysql.ParseGTIDSet(gmysql.MySQLFlavor, "") c.Assert(err, IsNil) gtidEventCount := 0 @@ -866,7 +866,7 @@ func (t *testReaderSuite) TestStartSyncByGTID(c *C) { } } excludeStr := strings.Join(excludeStrs, ",") - excludeGset, err := mysql.ParseGTIDSet(mysql.MySQLFlavor, excludeStr) + excludeGset, err := gmysql.ParseGTIDSet(gmysql.MySQLFlavor, excludeStr) c.Assert(err, IsNil) // StartSyncByGtid exclude first uuid @@ -942,7 +942,7 @@ func (t *testReaderSuite) TestStartSyncError(c *C) { UUIDs = []string{ "b60868af-5a6f-11e9-9ea3-0242ac160006.000001", } - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} startPos = gmysql.Position{Name: "test-mysql-bin|000001.000001"} // from the first relay log file in the first sub directory ) @@ -967,7 +967,7 @@ func (t *testReaderSuite) TestStartSyncError(c *C) { // write UUIDs into index file r = NewBinlogReader(log.L(), cfg) // create a new reader uuidBytes := t.uuidListToBytes(c, UUIDs) - err = ioutil.WriteFile(r.indexPath, uuidBytes, 0600) + err = ioutil.WriteFile(r.indexPath, uuidBytes, 0o600) c.Assert(err, IsNil) // the startup relay log file not found @@ -994,11 +994,11 @@ func (t *testReaderSuite) TestStartSyncError(c *C) { // too big startPos uuid := UUIDs[0] - err = os.MkdirAll(filepath.Join(baseDir, uuid), 0700) + err = os.MkdirAll(filepath.Join(baseDir, uuid), 0o700) c.Assert(err, IsNil) parsedStartPosName := "test-mysql-bin.000001" relayLogFilePath := filepath.Join(baseDir, uuid, parsedStartPosName) - err = ioutil.WriteFile(relayLogFilePath, make([]byte, 100), 0600) + err = ioutil.WriteFile(relayLogFilePath, make([]byte, 100), 0o600) c.Assert(err, IsNil) startPos.Pos = 10000 s, err = r.StartSyncByPos(startPos) @@ -1009,10 +1009,10 @@ func (t *testReaderSuite) TestStartSyncError(c *C) { func (t *testReaderSuite) TestAdvanceCurrentGTIDSet(c *C) { var ( baseDir = c.MkDir() - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) - mysqlGset, _ = mysql.ParseMysqlGTIDSet("b60868af-5a6f-11e9-9ea3-0242ac160006:1-6") - mariadbGset, _ = mysql.ParseMariadbGTIDSet("0-1-5") + mysqlGset, _ = gmysql.ParseMysqlGTIDSet("b60868af-5a6f-11e9-9ea3-0242ac160006:1-6") + mariadbGset, _ = gmysql.ParseMariadbGTIDSet("0-1-5") ) r.prevGset = mysqlGset.Clone() r.currGset = nil @@ -1026,7 +1026,7 @@ func (t *testReaderSuite) TestAdvanceCurrentGTIDSet(c *C) { c.Assert(mysqlGset.Equal(r.prevGset), IsTrue) c.Assert(r.currGset.String(), Equals, "b60868af-5a6f-11e9-9ea3-0242ac160006:1-7") - r.cfg.Flavor = mysql.MariaDBFlavor + r.cfg.Flavor = gmysql.MariaDBFlavor r.prevGset = mariadbGset.Clone() r.currGset = nil notUpdated, err = r.advanceCurrentGtidSet("0-1-3") @@ -1043,7 +1043,7 @@ func (t *testReaderSuite) TestAdvanceCurrentGTIDSet(c *C) { func (t *testReaderSuite) TestReParseUsingGTID(c *C) { var ( baseDir = c.MkDir() - cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: mysql.MySQLFlavor} + cfg = &BinlogReaderConfig{RelayDir: baseDir, Flavor: gmysql.MySQLFlavor} r = NewBinlogReader(log.L(), cfg) uuid = "ba8f633f-1f15-11eb-b1c7-0242ac110002.000001" gtidStr = "ba8f633f-1f15-11eb-b1c7-0242ac110002:1" @@ -1051,17 +1051,17 @@ func (t *testReaderSuite) TestReParseUsingGTID(c *C) { latestPos uint32 ) - startGTID, err := gtid.ParserGTID(mysql.MySQLFlavor, "") + startGTID, err := gtid.ParserGTID(gmysql.MySQLFlavor, "") c.Assert(err, IsNil) - lastGTID, err := gtid.ParserGTID(mysql.MySQLFlavor, gtidStr) + lastGTID, err := gtid.ParserGTID(gmysql.MySQLFlavor, gtidStr) c.Assert(err, IsNil) // prepare a minimal relay log file - c.Assert(ioutil.WriteFile(r.indexPath, []byte(uuid), 0600), IsNil) + c.Assert(ioutil.WriteFile(r.indexPath, []byte(uuid), 0o600), IsNil) uuidDir := path.Join(baseDir, uuid) - c.Assert(os.MkdirAll(uuidDir, 0700), IsNil) - f, err := os.OpenFile(path.Join(uuidDir, file), os.O_CREATE|os.O_WRONLY, 0600) + c.Assert(os.MkdirAll(uuidDir, 0o700), IsNil) + f, err := os.OpenFile(path.Join(uuidDir, file), os.O_CREATE|os.O_WRONLY, 0o600) c.Assert(err, IsNil) _, err = f.Write(replication.BinLogFileHeader) c.Assert(err, IsNil) @@ -1077,7 +1077,8 @@ func (t *testReaderSuite) TestReParseUsingGTID(c *C) { genType := []replication.EventType{ replication.PREVIOUS_GTIDS_EVENT, replication.QUERY_EVENT, - replication.XID_EVENT} + replication.XID_EVENT, + } events, _, _, latestGTIDSet := t.genEvents(c, genType, 4, lastGTID, startGTID) c.Assert(events, HasLen, 1+1+2+5) @@ -1149,7 +1150,7 @@ func (t *testReaderSuite) genBinlogEvents(c *C, latestPos uint32, latestGTID gti // for these tests, generates some DDL events is enough count := 5 + rand.Intn(5) for i := 0; i < count; i++ { - evs, err := event.GenDDLEvents(mysql.MySQLFlavor, 1, latestPos, latestGTID, fmt.Sprintf("db_%d", i), fmt.Sprintf("CREATE TABLE %d (c1 INT)", i)) + evs, err := event.GenDDLEvents(gmysql.MySQLFlavor, 1, latestPos, latestGTID, fmt.Sprintf("db_%d", i), fmt.Sprintf("CREATE TABLE %d (c1 INT)", i)) c.Assert(err, IsNil) events = append(events, evs.Events...) latestPos = evs.LatestPos @@ -1180,7 +1181,7 @@ func (t *testReaderSuite) genEvents(c *C, eventTypes []replication.EventType, la for i, eventType := range eventTypes { switch eventType { case replication.QUERY_EVENT: - evs, err := event.GenDDLEvents(mysql.MySQLFlavor, 1, latestPos, latestGTID, fmt.Sprintf("db_%d", i), fmt.Sprintf("CREATE TABLE %d (c1 int)", i)) + evs, err := event.GenDDLEvents(gmysql.MySQLFlavor, 1, latestPos, latestGTID, fmt.Sprintf("db_%d", i), fmt.Sprintf("CREATE TABLE %d (c1 int)", i)) c.Assert(err, IsNil) events = append(events, evs.Events...) latestPos = evs.LatestPos @@ -1201,7 +1202,7 @@ func (t *testReaderSuite) genEvents(c *C, eventTypes []replication.EventType, la Rows: [][]interface{}{{int32(1)}, {int32(2)}}, }, } - evs, err := event.GenDMLEvents(mysql.MySQLFlavor, 1, latestPos, latestGTID, replication.WRITE_ROWS_EVENTv2, 10, insertDMLData) + evs, err := event.GenDMLEvents(gmysql.MySQLFlavor, 1, latestPos, latestGTID, replication.WRITE_ROWS_EVENTv2, 10, insertDMLData) c.Assert(err, IsNil) events = append(events, evs.Events...) latestPos = evs.LatestPos @@ -1235,11 +1236,12 @@ func (t *testReaderSuite) purgeStreamer(c *C, s Streamer) { for { _, err := s.GetEvent(ctx) - if err == nil { + switch { + case err == nil: continue - } else if err == ctx.Err() { + case err == ctx.Err(): return - } else { + default: c.Fatalf("purge streamer with error %v", err) } } @@ -1255,9 +1257,9 @@ func (t *testReaderSuite) verifyNoEventsInStreamer(c *C, s Streamer) { } } -func (t *testReaderSuite) uuidListToBytes(c *C, UUIDs []string) []byte { +func (t *testReaderSuite) uuidListToBytes(c *C, uuids []string) []byte { var buf bytes.Buffer - for _, uuid := range UUIDs { + for _, uuid := range uuids { _, err := buf.WriteString(uuid) c.Assert(err, IsNil) _, err = buf.WriteString("\n") @@ -1266,10 +1268,11 @@ func (t *testReaderSuite) uuidListToBytes(c *C, UUIDs []string) []byte { return buf.Bytes() } -func (t *testReaderSuite) writeUUIDs(c *C, relayDir string, UUIDs []string) []byte { +// nolint:unparam +func (t *testReaderSuite) writeUUIDs(c *C, relayDir string, uuids []string) []byte { indexPath := path.Join(relayDir, utils.UUIDIndexFilename) var buf bytes.Buffer - for _, uuid := range UUIDs { + for _, uuid := range uuids { _, err := buf.WriteString(uuid) c.Assert(err, IsNil) _, err = buf.WriteString("\n") @@ -1277,7 +1280,7 @@ func (t *testReaderSuite) writeUUIDs(c *C, relayDir string, UUIDs []string) []by } // write the index file - err := ioutil.WriteFile(indexPath, buf.Bytes(), 0600) + err := ioutil.WriteFile(indexPath, buf.Bytes(), 0o600) c.Assert(err, IsNil) return buf.Bytes() } diff --git a/pkg/streamer/streamer.go b/pkg/streamer/streamer.go index 6023034540..f7fd0156d2 100644 --- a/pkg/streamer/streamer.go +++ b/pkg/streamer/streamer.go @@ -27,9 +27,7 @@ import ( "go.uber.org/zap" ) -var ( - heartbeatInterval = common.MasterHeartbeatPeriod -) +var heartbeatInterval = common.MasterHeartbeatPeriod // TODO: maybe one day we can make a pull request to go-mysql to support LocalStreamer. diff --git a/pkg/streamer/streamer_test.go b/pkg/streamer/streamer_test.go index cd2026fe61..24e0c2a95e 100644 --- a/pkg/streamer/streamer_test.go +++ b/pkg/streamer/streamer_test.go @@ -28,8 +28,7 @@ import ( var _ = Suite(&testStreamerSuite{}) -type testStreamerSuite struct { -} +type testStreamerSuite struct{} func (t *testStreamerSuite) TestStreamer(c *C) { c.Assert(failpoint.Enable("github.com/pingcap/dm/pkg/streamer/SetHeartbeatInterval", "return(10000)"), IsNil) diff --git a/pkg/streamer/util.go b/pkg/streamer/util.go index f75e210262..e39e0c4683 100644 --- a/pkg/streamer/util.go +++ b/pkg/streamer/util.go @@ -24,10 +24,10 @@ import ( ) // getNextUUID gets (the nextUUID and its suffix) after the current UUID. -func getNextUUID(currUUID string, UUIDs []string) (string, string, error) { - for i := len(UUIDs) - 2; i >= 0; i-- { - if UUIDs[i] == currUUID { - nextUUID := UUIDs[i+1] +func getNextUUID(currUUID string, uuids []string) (string, string, error) { + for i := len(uuids) - 2; i >= 0; i-- { + if uuids[i] == currUUID { + nextUUID := uuids[i+1] _, suffixInt, err := utils.ParseSuffixForUUID(nextUUID) if err != nil { return "", "", terror.Annotatef(err, "UUID %s", nextUUID) diff --git a/pkg/streamer/util_test.go b/pkg/streamer/util_test.go index a198d896f5..f82cfe5a72 100644 --- a/pkg/streamer/util_test.go +++ b/pkg/streamer/util_test.go @@ -27,8 +27,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testUtilSuite struct { -} +type testUtilSuite struct{} func (t *testUtilSuite) TestGetNextUUID(c *C) { UUIDs := []string{ diff --git a/pkg/terror/error_list.go b/pkg/terror/error_list.go index e8e6e28934..914e6e105b 100644 --- a/pkg/terror/error_list.go +++ b/pkg/terror/error_list.go @@ -13,7 +13,7 @@ package terror -// Database operation error code list +// Database operation error code list. const ( codeDBDriverError ErrCode = iota + 10001 codeDBBadConn @@ -23,7 +23,7 @@ const ( codeDBExecuteFailed ) -// Functional error code list +// Functional error code list. const ( codeParseMydumperMeta ErrCode = iota + 11001 codeGetFileSize @@ -47,7 +47,7 @@ const ( codeReaderAlreadyStarted codeReaderStateCannotClose codeReaderShouldStartSync - // pkg/streamer + // pkg/streamer. codeEmptyRelayDir codeReadDir codeBaseFileNotFound @@ -67,7 +67,7 @@ const ( codeNoSubdirToSwitch codeNeedSyncAgain codeSyncClosed - // pkg/utils + // pkg/utils. codeSchemaTableNameNotValid codeGenTableRouter codeEncryptSecretKeyNotValid @@ -77,7 +77,7 @@ const ( codeCiphertextContextNotValid codeInvalidBinlogPosStr codeEncCipherTextBase64Decode - // pkg/binlog + // pkg/binlog. codeBinlogWriteBinaryData codeBinlogWriteDataToBuffer codeBinlogHeaderLengthNotValid @@ -125,69 +125,69 @@ const ( codeBinlogParseMariaDBGTIDSet codeBinlogMariaDBAddGTIDSet - // pkg/tracing + // pkg/tracing. codeTracingEventDataNotValid codeTracingUploadData codeTracingEventTypeNotValid codeTracingGetTraceCode codeTracingDataChecksum codeTracingGetTSO - // pkg/backoff + // pkg/backoff. codeBackoffArgsNotValid codeInitLoggerFail - // pkg/gtid + // pkg/gtid. codeGTIDTruncateInvalid - // pkg/streamer + // pkg/streamer. codeRelayLogGivenPosTooBig - // pkg/election + // pkg/election. codeElectionCampaignFail codeElectionGetLeaderIDFail - // pkg/binlog + // pkg/binlog. codeBinlogInvalidFilenameWithUUIDSuffix - // dm/common + // dm/common. codeDecodeEtcdKeyFail - // pkg/shardddl/optimism + // pkg/shardddl/optimism. codeShardDDLOptimismTrySyncFail - // pkg/conn + // pkg/conn. codeConnInvalidTLSConfig codeConnRegistryTLSConfig - // pkg/upgrade + // pkg/upgrade. codeUpgradeVersionEtcdFail - // pkg/v1workermeta + // pkg/v1workermeta. codeInvalidV1WorkerMetaPath - // pkg/v1dbschema + // pkg/v1dbschema. codeFailUpdateV1DBSchema - // pkg/binlog + // pkg/binlog. codeBinlogStatusVarsParse - // dm/command + // dm/command. codeVerifyHandleErrorArgs - // pkg/parser + // pkg/parser. codeRewriteSQL - // pkg/streamer + // pkg/streamer. codeNoUUIDDirMatchGTID codeNoRelayPosMatchGTID codeReaderReachEndOfFile - // pkg/dumpling + // pkg/dumpling. codeMetadataNoBinlogLoc - // pkg/streamer + // pkg/streamer. codePreviousGTIDNotExist ) -// Config related error code list +// Config related error code list. const ( codeConfigCheckItemNotSupport ErrCode = iota + 20001 codeConfigTomlTransform @@ -229,14 +229,14 @@ const ( codeConfigGlobalConfigsUnused ) -// Binlog operation error code list +// Binlog operation error code list. const ( codeBinlogExtractPosition ErrCode = iota + 22001 codeBinlogInvalidFilename codeBinlogParsePosFromStr ) -// Checkpoint error code +// Checkpoint error code. const ( codeCheckpointInvalidTaskMode ErrCode = iota + 24001 codeCheckpointSaveInvalidPos @@ -246,7 +246,7 @@ const ( codeCheckpointRestoreCountGreater ) -// Task check error code +// Task check error code. const ( codeTaskCheckSameTableName ErrCode = iota + 26001 codeTaskCheckFailedOpenDB @@ -257,7 +257,7 @@ const ( codeSourceCheckGTID ) -// Relay log utils error code +// Relay log utils error code. const ( codeRelayParseUUIDIndex ErrCode = iota + 28001 codeRelayParseUUIDSuffix @@ -266,7 +266,7 @@ const ( codeRelayNoValidRelaySubDir ) -// Relay unit error code +// Relay unit error code. const ( codeRelayUUIDSuffixNotValid ErrCode = iota + 30001 codeRelayUUIDSuffixLessThanPrev @@ -314,7 +314,7 @@ const ( codeRotateEventWithDifferentServerID ) -// Dump unit error code +// Dump unit error code. const ( codeDumpUnitRuntime ErrCode = iota + 32001 codeDumpUnitGenTableRouter @@ -322,7 +322,7 @@ const ( codeDumpUnitGlobalLock ) -// Load unit error code +// Load unit error code. const ( codeLoadUnitCreateSchemaFile ErrCode = iota + 34001 codeLoadUnitInvalidFileEnding @@ -342,7 +342,7 @@ const ( codeLoadUnitGenBAList ) -// Sync unit error code +// Sync unit error code. const ( codeSyncerUnitPanic ErrCode = iota + 36001 codeSyncUnitInvalidTableName @@ -414,7 +414,7 @@ const ( codeSyncerUnsupportedStmt ) -// DM-master error code +// DM-master error code. const ( codeMasterSQLOpNilRequest ErrCode = iota + 38001 codeMasterSQLOpNotSupport @@ -473,7 +473,7 @@ const ( codeMasterOptimisticTableInfobeforeNotExist ) -// DM-worker error code +// DM-worker error code. const ( codeWorkerParseFlagSet ErrCode = iota + 40001 codeWorkerInvalidFlag @@ -556,7 +556,7 @@ const ( codeWorkerRelayConfigChanging ) -// DM-tracer error code +// DM-tracer error code. const ( codeTracerParseFlagSet ErrCode = iota + 42001 codeTracerConfigTomlTransform @@ -570,7 +570,7 @@ const ( codeTracerStartService ) -// Schema-tracker error code +// Schema-tracker error code. const ( codeSchemaTrackerInvalidJSON ErrCode = iota + 44001 codeSchemaTrackerCannotCreateSchema @@ -613,20 +613,20 @@ const ( codeSchedulerSourceOpRelayExist ) -// dmctl error code +// dmctl error code. const ( codeCtlGRPCCreateConn ErrCode = iota + 48001 codeCtlInvalidTLSCfg ) -// default error code +// default error code. const ( codeNotSet ErrCode = iota + 50000 ) -// Error instances +// Error instances. var ( - // Database operation related error + // Database operation related error. ErrDBDriverError = New(codeDBDriverError, ClassDatabase, ScopeNotSet, LevelHigh, "database driver error", "Please check the database connection and the database config in configuration file.") ErrDBBadConn = New(codeDBBadConn, ClassDatabase, ScopeNotSet, LevelHigh, "database driver", "Please check the database connection, then use `pause-task` to pause the task and then use `resume-task` to resume the task.") ErrDBInvalidConn = New(codeDBInvalidConn, ClassDatabase, ScopeNotSet, LevelHigh, "database driver", "Please check the database connection, then use `pause-task` to stop the task and then use `resume-task` to resume the task.") @@ -635,7 +635,7 @@ var ( ErrDBQueryFailed = New(codeDBQueryFailed, ClassDatabase, ScopeNotSet, LevelHigh, "query statement failed: %s", "") ErrDBExecuteFailed = New(codeDBExecuteFailed, ClassDatabase, ScopeNotSet, LevelHigh, "execute statement failed: %s", "") - // Functional error + // Functional error. ErrParseMydumperMeta = New(codeParseMydumperMeta, ClassFunctional, ScopeInternal, LevelHigh, "parse mydumper metadata error: %s, metadata: %s", "") ErrGetFileSize = New(codeGetFileSize, ClassFunctional, ScopeInternal, LevelHigh, "get file %s size", "") ErrDropMultipleTables = New(codeDropMultipleTables, ClassFunctional, ScopeInternal, LevelHigh, "not allowed operation: drop multiple tables in one statement", "It is recommended to include only one DDL operation in a statement executed upstream. Please manually handle it using dmctl (skipping the DDL statement or replacing the DDL statement with a specified DDL statement). For details, see https://docs.pingcap.com/tidb-data-migration/stable/handle-failed-sql-statements") @@ -658,7 +658,7 @@ var ( ErrReaderAlreadyStarted = New(codeReaderAlreadyStarted, ClassFunctional, ScopeInternal, LevelHigh, "stage %s, expect %s, already started", "") ErrReaderStateCannotClose = New(codeReaderStateCannotClose, ClassFunctional, ScopeInternal, LevelHigh, "stage %s, expect %s, can not close", "") ErrReaderShouldStartSync = New(codeReaderShouldStartSync, ClassFunctional, ScopeInternal, LevelHigh, "stage %s, expect %s", "") - // pkg/streamer + // pkg/streamer. ErrEmptyRelayDir = New(codeEmptyRelayDir, ClassFunctional, ScopeInternal, LevelHigh, "empty relay dir", "Please check `relay-dir` config in task configuration file.") ErrReadDir = New(codeReadDir, ClassFunctional, ScopeInternal, LevelHigh, "read dir: %s", "") ErrBaseFileNotFound = New(codeBaseFileNotFound, ClassFunctional, ScopeInternal, LevelHigh, "base file %s in directory %s not found", "") @@ -678,7 +678,7 @@ var ( ErrNoSubdirToSwitch = New(codeNoSubdirToSwitch, ClassFunctional, ScopeInternal, LevelHigh, "parse for previous sub relay directory finished, but no next sub directory need to switch", "") ErrNeedSyncAgain = New(codeNeedSyncAgain, ClassFunctional, ScopeInternal, LevelHigh, "Last sync error or closed, try sync and get event again", "") ErrSyncClosed = New(codeSyncClosed, ClassFunctional, ScopeInternal, LevelHigh, "Sync was closed", "") - // pkg/utils + // pkg/utils. ErrSchemaTableNameNotValid = New(codeSchemaTableNameNotValid, ClassFunctional, ScopeInternal, LevelHigh, "table name %s not valid", "") ErrGenTableRouter = New(codeGenTableRouter, ClassFunctional, ScopeInternal, LevelHigh, "generate table router", "Please check `routes` config in task configuration file.") ErrEncryptSecretKeyNotValid = New(codeEncryptSecretKeyNotValid, ClassFunctional, ScopeInternal, LevelHigh, "key size should be 16, 24 or 32, but input key's size is %d", "") @@ -688,7 +688,7 @@ var ( ErrCiphertextContextNotValid = New(codeCiphertextContextNotValid, ClassFunctional, ScopeInternal, LevelHigh, "ciphertext's content not valid", "") ErrInvalidBinlogPosStr = New(codeInvalidBinlogPosStr, ClassFunctional, ScopeInternal, LevelHigh, "invalid mysql position string: %s", "") ErrEncCipherTextBase64Decode = New(codeEncCipherTextBase64Decode, ClassFunctional, ScopeInternal, LevelHigh, "decode base64 encoded password %s", "") - // pkg/binlog + // pkg/binlog. ErrBinlogWriteBinaryData = New(codeBinlogWriteBinaryData, ClassFunctional, ScopeInternal, LevelHigh, "", "") ErrBinlogWriteDataToBuffer = New(codeBinlogWriteDataToBuffer, ClassFunctional, ScopeInternal, LevelHigh, "", "") ErrBinlogHeaderLengthNotValid = New(codeBinlogHeaderLengthNotValid, ClassFunctional, ScopeInternal, LevelHigh, "header length should be %d, but got %d not valid", "") @@ -736,67 +736,67 @@ var ( ErrBinlogParseMariaDBGTIDSet = New(codeBinlogParseMariaDBGTIDSet, ClassFunctional, ScopeInternal, LevelHigh, "parse MariaDB GTID set", "") ErrBinlogMariaDBAddGTIDSet = New(codeBinlogMariaDBAddGTIDSet, ClassFunctional, ScopeInternal, LevelHigh, "add set %v to GTID set", "") - // pkg/tracing + // pkg/tracing. ErrTracingEventDataNotValid = New(codeTracingEventDataNotValid, ClassFunctional, ScopeInternal, LevelHigh, "invalid event data for type: %s", "") ErrTracingUploadData = New(codeTracingUploadData, ClassFunctional, ScopeInternal, LevelHigh, "upload event", "") ErrTracingEventTypeNotValid = New(codeTracingEventTypeNotValid, ClassFunctional, ScopeInternal, LevelHigh, "invalid event type %s, will not process", "") ErrTracingGetTraceCode = New(codeTracingGetTraceCode, ClassFunctional, ScopeInternal, LevelHigh, "failed to get code information from runtime.Caller", "") ErrTracingDataChecksum = New(codeTracingDataChecksum, ClassFunctional, ScopeInternal, LevelHigh, "calc data checksum", "") ErrTracingGetTSO = New(codeTracingGetTSO, ClassFunctional, ScopeInternal, LevelHigh, "get tso", "") - // pkg/backoff + // pkg/backoff. ErrBackoffArgsNotValid = New(codeBackoffArgsNotValid, ClassFunctional, ScopeInternal, LevelMedium, "backoff argument %s value %v not valid", "") - // pkg + // pkg. ErrInitLoggerFail = New(codeInitLoggerFail, ClassFunctional, ScopeInternal, LevelMedium, "init logger failed", "") - // pkg/gtid + // pkg/gtid. ErrGTIDTruncateInvalid = New(codeGTIDTruncateInvalid, ClassFunctional, ScopeInternal, LevelHigh, "truncate GTID sets %v to %v not valid", "") - // pkg/streamer + // pkg/streamer. ErrRelayLogGivenPosTooBig = New(codeRelayLogGivenPosTooBig, ClassFunctional, ScopeInternal, LevelHigh, "the given relay log pos %s of meta config is too big, please check it again", "If the size of the corresponding binlog file has exceeded 4GB, please follow the solution in https://docs.pingcap.com/tidb-data-migration/stable/error-handling#the-relay-unit-throws-error-event-from--in--diff-from-passed-in-event--or-a-replication-task-is-interrupted-with-failing-to-get-or-parse-binlog-errors-like-get-binlog-error-error-1236-hy000-and-binlog-checksum-mismatch-data-may-be-corrupted-returned") - // pkg/election + // pkg/election. ErrElectionCampaignFail = New(codeElectionCampaignFail, ClassFunctional, ScopeInternal, LevelHigh, "fail to campaign leader: %s", "") ErrElectionGetLeaderIDFail = New(codeElectionGetLeaderIDFail, ClassFunctional, ScopeInternal, LevelMedium, "fail to get leader ID", "") - // pkg/binlog + // pkg/binlog. ErrBinlogInvalidFilenameWithUUIDSuffix = New(codeBinlogInvalidFilenameWithUUIDSuffix, ClassFunctional, ScopeInternal, LevelHigh, "invalid binlog filename with uuid suffix %s", "") - // dm/common + // dm/common. ErrDecodeEtcdKeyFail = New(codeDecodeEtcdKeyFail, ClassFunctional, ScopeInternal, LevelMedium, "fail to decode etcd key: %s", "") - // pkg/shardddl/optimism + // pkg/shardddl/optimism. ErrShardDDLOptimismTrySyncFail = New(codeShardDDLOptimismTrySyncFail, ClassFunctional, ScopeInternal, LevelMedium, "fail to try sync the optimistic shard ddl lock %s: %s", "Please use `show-ddl-locks` command for more details.") - // pkg/conn + // pkg/conn. ErrConnInvalidTLSConfig = New(codeConnInvalidTLSConfig, ClassFunctional, ScopeInternal, LevelMedium, "invalid TLS config", "Please check the `ssl-ca`, `ssl-cert` and `ssl-key` config.") ErrConnRegistryTLSConfig = New(codeConnRegistryTLSConfig, ClassFunctional, ScopeInternal, LevelMedium, "fail to registry TLS config", "") - // pkg/upgrade + // pkg/upgrade. ErrUpgradeVersionEtcdFail = New(codeUpgradeVersionEtcdFail, ClassFunctional, ScopeInternal, LevelHigh, "fail to operate DM cluster version in etcd", "Please use `list-member --master` to confirm whether the DM-master cluster is healthy") - // pkg/v1workermeta + // pkg/v1workermeta. ErrInvalidV1WorkerMetaPath = New(codeInvalidV1WorkerMetaPath, ClassFunctional, ScopeInternal, LevelMedium, "%s is an invalid v1.0.x DM-worker meta path", "Please check no `meta-dir` set for v1.0.x DM-worker.") - // pkg/v1dbschema + // pkg/v1dbschema. ErrFailUpdateV1DBSchema = New(codeFailUpdateV1DBSchema, ClassFunctional, ScopeInternal, LevelMedium, "fail to upgrade v1.0.x DB schema", "Please confirm that you have not violated any restrictions in the upgrade documentation.") - // pkg/binlog + // pkg/binlog. ErrBinlogStatusVarsParse = New(codeBinlogStatusVarsParse, ClassFunctional, ScopeInternal, LevelMedium, "fail to parse binglog status_vars: %v, offset: %d", "") - // Functional error + // Functional error. ErrVerifyHandleErrorArgs = New(codeVerifyHandleErrorArgs, ClassFunctional, ScopeInternal, LevelLow, "", "Please make sure the args are correct.") - // pkg/parser + // pkg/parser. ErrRewriteSQL = New(codeRewriteSQL, ClassFunctional, ScopeInternal, LevelHigh, "failed to rewrite SQL for target DB, stmt: %+v, targetTableNames: %+v", "") - // pkg/streamer + // pkg/streamer. ErrNoUUIDDirMatchGTID = New(codeNoUUIDDirMatchGTID, ClassFunctional, ScopeInternal, LevelHigh, "no relay subdir match gtid %s", "") ErrNoRelayPosMatchGTID = New(codeNoRelayPosMatchGTID, ClassFunctional, ScopeInternal, LevelHigh, "no relay pos match gtid %s", "") ErrReaderReachEndOfFile = New(codeReaderReachEndOfFile, ClassFunctional, ScopeInternal, LevelLow, "", "") - // pkg/dumplling + // pkg/dumplling. ErrMetadataNoBinlogLoc = New(codeMetadataNoBinlogLoc, ClassFunctional, ScopeUpstream, LevelLow, "didn't found binlog location in dumped metadata file %s", "Please check log of dump unit, there maybe errors when read upstream binlog status") ErrPreviousGTIDNotExist = New(codePreviousGTIDNotExist, ClassFunctional, ScopeInternal, LevelHigh, "no previous gtid event from binlog %s", "") - // Config related error + // Config related error. ErrConfigCheckItemNotSupport = New(codeConfigCheckItemNotSupport, ClassConfig, ScopeInternal, LevelMedium, "checking item %s is not supported\n%s", "Please check `ignore-checking-items` config in task configuration file, which can be set including `all`/`dump_privilege`/`replication_privilege`/`version`/`binlog_enable`/`binlog_format`/`binlog_row_image`/`table_schema`/`schema_of_shard_tables`/`auto_increment_ID`.") ErrConfigTomlTransform = New(codeConfigTomlTransform, ClassConfig, ScopeInternal, LevelMedium, "%s", "Please check the configuration file has correct TOML format.") ErrConfigYamlTransform = New(codeConfigYamlTransform, ClassConfig, ScopeInternal, LevelMedium, "%s", "Please check the configuration file has correct YAML format.") @@ -836,12 +836,12 @@ var ( ErrConfigBinlogEventFilter = New(codeConfigBinlogEventFilter, ClassConfig, ScopeInternal, LevelHigh, "generate binlog event filter", "Please check the `filters` config in source and task configuration files.") ErrConfigGlobalConfigsUnused = New(codeConfigGlobalConfigsUnused, ClassConfig, ScopeInternal, LevelHigh, "The configurations as following %v are set in global configuration but instances don't use them", "Please check the configuration files.") - // Binlog operation error + // Binlog operation error. ErrBinlogExtractPosition = New(codeBinlogExtractPosition, ClassBinlogOp, ScopeInternal, LevelHigh, "", "") ErrBinlogInvalidFilename = New(codeBinlogInvalidFilename, ClassBinlogOp, ScopeInternal, LevelHigh, "invalid binlog filename", "") ErrBinlogParsePosFromStr = New(codeBinlogParsePosFromStr, ClassBinlogOp, ScopeInternal, LevelHigh, "", "") - // Checkpoint error + // Checkpoint error. ErrCheckpointInvalidTaskMode = New(codeCheckpointInvalidTaskMode, ClassCheckpoint, ScopeInternal, LevelMedium, "invalid task mode: %s", "") ErrCheckpointSaveInvalidPos = New(codeCheckpointSaveInvalidPos, ClassCheckpoint, ScopeInternal, LevelHigh, "save point %s is older than current location %s", "") ErrCheckpointInvalidTableFile = New(codeCheckpointInvalidTableFile, ClassCheckpoint, ScopeInternal, LevelMedium, "invalid db table sql file - %s", "") @@ -849,7 +849,7 @@ var ( ErrCheckpointTableNotExistInFile = New(codeCheckpointTableNotExistInFile, ClassCheckpoint, ScopeInternal, LevelMedium, "table (%s) not exist in db (%s) data files, but in checkpoint", "") ErrCheckpointRestoreCountGreater = New(codeCheckpointRestoreCountGreater, ClassCheckpoint, ScopeInternal, LevelMedium, "restoring count greater than total count for table[%v]", "") - // Task check error + // Task check error. ErrTaskCheckSameTableName = New(codeTaskCheckSameTableName, ClassTaskCheck, ScopeInternal, LevelMedium, "same table name in case-insensitive %v", "Please check `target-table` config in task configuration file.") ErrTaskCheckFailedOpenDB = New(codeTaskCheckFailedOpenDB, ClassTaskCheck, ScopeInternal, LevelHigh, "failed to open DSN %s:***@%s:%d", "Please check the database config in configuration file.") ErrTaskCheckGenTableRouter = New(codeTaskCheckGenTableRouter, ClassTaskCheck, ScopeInternal, LevelMedium, "generate table router error", "Please check the `routes` config in task configuration file.") @@ -858,14 +858,14 @@ var ( ErrTaskCheckGenBAList = New(codeTaskCheckGenBAList, ClassTaskCheck, ScopeInternal, LevelMedium, "generate block allow list error", "Please check the `block-allow-list` config in task configuration file.") ErrSourceCheckGTID = New(codeSourceCheckGTID, ClassTaskCheck, ScopeInternal, LevelMedium, "%s has GTID_MODE = %s instead of ON", "Please check the `enable-gtid` config in source configuration file.") - // Relay log basic API error + // Relay log basic API error. ErrRelayParseUUIDIndex = New(codeRelayParseUUIDIndex, ClassRelayEventLib, ScopeInternal, LevelHigh, "parse server-uuid.index", "") ErrRelayParseUUIDSuffix = New(codeRelayParseUUIDSuffix, ClassRelayEventLib, ScopeInternal, LevelHigh, "UUID (with suffix) %s not valid", "") ErrRelayUUIDWithSuffixNotFound = New(codeRelayUUIDWithSuffixNotFound, ClassRelayEventLib, ScopeInternal, LevelHigh, "no UUID (with suffix) matched %s found in %s, all UUIDs are %v", "") ErrRelayGenFakeRotateEvent = New(codeRelayGenFakeRotateEvent, ClassRelayEventLib, ScopeInternal, LevelHigh, "generate fake rotate event", "") ErrRelayNoValidRelaySubDir = New(codeRelayNoValidRelaySubDir, ClassRelayEventLib, ScopeInternal, LevelHigh, "there aren't any data under relay log directory %s.", "Please check relay log using query-status.") - // Relay unit error + // Relay unit error. ErrRelayUUIDSuffixNotValid = New(codeRelayUUIDSuffixNotValid, ClassRelayUnit, ScopeInternal, LevelHigh, "UUID %s suffix %d should be 1 larger than previous suffix %d", "") ErrRelayUUIDSuffixLessThanPrev = New(codeRelayUUIDSuffixLessThanPrev, ClassRelayUnit, ScopeInternal, LevelHigh, "previous UUID %s has suffix larger than %s", "") ErrRelayLoadMetaData = New(codeRelayLoadMetaData, ClassRelayUnit, ScopeInternal, LevelHigh, "load meta data", "") @@ -911,13 +911,13 @@ var ( ErrPreviousGTIDsNotValid = New(codePreviousGTIDsNotValid, ClassRelayUnit, ScopeInternal, LevelHigh, "previousGTIDs %s not valid", "") ErrRotateEventWithDifferentServerID = New(codeRotateEventWithDifferentServerID, ClassRelayUnit, ScopeInternal, LevelHigh, "receive fake rotate event with different server_id", "Please use `resume-relay` command if upstream database has changed") - // Dump unit error + // Dump unit error. ErrDumpUnitRuntime = New(codeDumpUnitRuntime, ClassDumpUnit, ScopeInternal, LevelHigh, "mydumper/dumpling runs with error, with output (may empty): %s", "") ErrDumpUnitGenTableRouter = New(codeDumpUnitGenTableRouter, ClassDumpUnit, ScopeInternal, LevelHigh, "generate table router", "Please check `routes` config in task configuration file.") ErrDumpUnitGenBAList = New(codeDumpUnitGenBAList, ClassDumpUnit, ScopeInternal, LevelHigh, "generate block allow list", "Please check the `block-allow-list` config in task configuration file.") ErrDumpUnitGlobalLock = New(codeDumpUnitGlobalLock, ClassDumpUnit, ScopeInternal, LevelHigh, "Couldn't acquire global lock", "Please check upstream privilege about FTWRL, or add `--no-locks` or `--consistency none` to extra-args of mydumpers") - // Load unit error + // Load unit error. ErrLoadUnitCreateSchemaFile = New(codeLoadUnitCreateSchemaFile, ClassLoadUnit, ScopeInternal, LevelMedium, "generate schema file", "Please check the `loaders` config in task configuration file.") ErrLoadUnitInvalidFileEnding = New(codeLoadUnitInvalidFileEnding, ClassLoadUnit, ScopeInternal, LevelHigh, "corresponding ending of sql: ')' not found", "") ErrLoadUnitParseQuoteValues = New(codeLoadUnitParseQuoteValues, ClassLoadUnit, ScopeInternal, LevelHigh, "parse quote values error", "") @@ -935,7 +935,7 @@ var ( ErrLoadUnitDuplicateTableFile = New(codeLoadUnitDuplicateTableFile, ClassLoadUnit, ScopeInternal, LevelHigh, "invalid table schema file, duplicated item - %s", "") ErrLoadUnitGenBAList = New(codeLoadUnitGenBAList, ClassLoadUnit, ScopeInternal, LevelHigh, "generate block allow list", "Please check the `block-allow-list` config in task configuration file.") - // Sync unit error + // Sync unit error. ErrSyncerUnitPanic = New(codeSyncerUnitPanic, ClassSyncUnit, ScopeInternal, LevelHigh, "panic error: %v", "") ErrSyncUnitInvalidTableName = New(codeSyncUnitInvalidTableName, ClassSyncUnit, ScopeInternal, LevelHigh, "extract table name for DML error: %s", "") ErrSyncUnitTableNameQuery = New(codeSyncUnitTableNameQuery, ClassSyncUnit, ScopeInternal, LevelHigh, "table name parse error: %s", "") @@ -949,7 +949,7 @@ var ( ErrSyncUnitShardingGroupNotFound = New(codeSyncUnitShardingGroupNotFound, ClassSyncUnit, ScopeInternal, LevelHigh, "sharding group for `%s`.`%s` not found", "") ErrSyncUnitSafeModeSetCount = New(codeSyncUnitSafeModeSetCount, ClassSyncUnit, ScopeInternal, LevelHigh, "", "") ErrSyncUnitCausalityConflict = New(codeSyncUnitCausalityConflict, ClassSyncUnit, ScopeInternal, LevelHigh, "some conflicts in causality, must be resolved", "") - // ErrSyncUnitDMLStatementFound defines an error which means we found unexpected dml statement found in query event + // ErrSyncUnitDMLStatementFound defines an error which means we found unexpected dml statement found in query event. ErrSyncUnitDMLStatementFound = New(codeSyncUnitDMLStatementFound, ClassSyncUnit, ScopeInternal, LevelHigh, "only support ROW format binlog, unexpected DML statement found in query event", "") ErrSyncerUnitBinlogEventFilter = New(codeSyncerUnitBinlogEventFilter, ClassSyncUnit, ScopeInternal, LevelHigh, "", "") ErrSyncerUnitInvalidReplicaEvent = New(codeSyncerUnitInvalidReplicaEvent, ClassSyncUnit, ScopeInternal, LevelHigh, "invalid replication event type %v", "") @@ -1006,7 +1006,7 @@ var ( ErrSyncerParseDDL = New(codeSyncerParseDDL, ClassSyncUnit, ScopeInternal, LevelHigh, "parse DDL: %s", "Please confirm your DDL statement is correct and needed. For TiDB compatible DDL, see https://docs.pingcap.com/tidb/stable/mysql-compatibility#ddl. You can use `handle-error` command to skip or replace the DDL or add a binlog filter rule to ignore it if the DDL is not needed.") ErrSyncerUnsupportedStmt = New(codeSyncerUnsupportedStmt, ClassSyncUnit, ScopeInternal, LevelHigh, "`%s` statement not supported in %s mode", "") - // DM-master error + // DM-master error. ErrMasterSQLOpNilRequest = New(codeMasterSQLOpNilRequest, ClassDMMaster, ScopeInternal, LevelMedium, "nil request not valid", "") ErrMasterSQLOpNotSupport = New(codeMasterSQLOpNotSupport, ClassDMMaster, ScopeInternal, LevelMedium, "op %s not supported", "") ErrMasterSQLOpWithoutSharding = New(codeMasterSQLOpWithoutSharding, ClassDMMaster, ScopeInternal, LevelMedium, "operate request without --sharding specified not valid", "") @@ -1068,7 +1068,7 @@ var ( ErrMasterInconsistentOptimisticDDLsAndInfo = New(codeMasterInconsistentOptimistDDLsAndInfo, ClassDMMaster, ScopeInternal, LevelHigh, "inconsistent count of optimistic ddls and table infos, ddls: %d, table info: %d", "") ErrMasterOptimisticTableInfoBeforeNotExist = New(codeMasterOptimisticTableInfobeforeNotExist, ClassDMMaster, ScopeInternal, LevelHigh, "table-info-before not exist in optimistic ddls: %v", "") - // DM-worker error + // DM-worker error. ErrWorkerParseFlagSet = New(codeWorkerParseFlagSet, ClassDMWorker, ScopeInternal, LevelMedium, "parse dm-worker config flag set", "") ErrWorkerInvalidFlag = New(codeWorkerInvalidFlag, ClassDMWorker, ScopeInternal, LevelMedium, "'%s' is an invalid flag", "") ErrWorkerDecodeConfigFromFile = New(codeWorkerDecodeConfigFromFile, ClassDMWorker, ScopeInternal, LevelMedium, "toml decode file", "Please check the configuration file has correct TOML format.") @@ -1150,7 +1150,7 @@ var ( ErrWorkerFailConnectMaster = New(codeWorkerFailConnectMaster, ClassDMWorker, ScopeInternal, LevelHigh, "cannot connect with master endpoints: %v", "Please check network connection of worker") ErrWorkerRelayConfigChanging = New(codeWorkerRelayConfigChanging, ClassDMWorker, ScopeInternal, LevelLow, "relay config of worker %s is changed too frequently, last relay source %s:, new relay source %s", "Please try again later") - // DM-tracer error + // DM-tracer error. ErrTracerParseFlagSet = New(codeTracerParseFlagSet, ClassDMTracer, ScopeInternal, LevelMedium, "parse dm-tracer config flag set", "") ErrTracerConfigTomlTransform = New(codeTracerConfigTomlTransform, ClassDMTracer, ScopeInternal, LevelMedium, "config toml transform", "Please check the configuration file has correct TOML format.") ErrTracerConfigInvalidFlag = New(codeTracerConfigInvalidFlag, ClassDMTracer, ScopeInternal, LevelMedium, "'%s' is an invalid flag", "") @@ -1162,7 +1162,7 @@ var ( ErrTracerEventTypeNotValid = New(codeTracerEventTypeNotValid, ClassDMTracer, ScopeInternal, LevelHigh, "trace event type %d not valid", "") ErrTracerStartService = New(codeTracerStartService, ClassDMTracer, ScopeInternal, LevelHigh, "start server", "") - // Schema-tracker error + // Schema-tracker error. ErrSchemaTrackerInvalidJSON = New(codeSchemaTrackerInvalidJSON, ClassSchemaTracker, ScopeDownstream, LevelHigh, "saved schema of `%s`.`%s` is not proper JSON", "") ErrSchemaTrackerCannotCreateSchema = New(codeSchemaTrackerCannotCreateSchema, ClassSchemaTracker, ScopeInternal, LevelHigh, "failed to create database for `%s` in schema tracker", "") ErrSchemaTrackerCannotCreateTable = New(codeSchemaTrackerCannotCreateTable, ClassSchemaTracker, ScopeInternal, LevelHigh, "failed to create table for `%s`.`%s` in schema tracker", "") @@ -1184,7 +1184,7 @@ var ( "failed to drop table for `%s`.`%s` in schema tracker", "") ErrSchemaTrackerInit = New(codeSchemaTrackerInit, ClassSchemaTracker, ScopeInternal, LevelHigh, "failed to create schema tracker", "") - // HA scheduler + // HA scheduler. ErrSchedulerNotStarted = New(codeSchedulerNotStarted, ClassScheduler, ScopeInternal, LevelHigh, "the scheduler has not started", "") ErrSchedulerStarted = New(codeSchedulerStarted, ClassScheduler, ScopeInternal, LevelMedium, "the scheduler has already started", "") ErrSchedulerWorkerExist = New(codeSchedulerWorkerExist, ClassScheduler, ScopeInternal, LevelMedium, "dm-worker with name %s already exists", "") @@ -1209,10 +1209,10 @@ var ( ErrSchedulerRelayWorkersWrongRelay = New(codeSchedulerRelayWorkersWrongRelay, ClassScheduler, ScopeInternal, LevelHigh, "these workers %s have started relay for another sources %s respectively", "Please correct sources in `stop-relay`.") ErrSchedulerSourceOpRelayExist = New(codeSchedulerSourceOpRelayExist, ClassScheduler, ScopeInternal, LevelHigh, "source with name %s need to operate has existing relay workers %s", "Please `stop-relay` first.") - // dmctl + // dmctl. ErrCtlGRPCCreateConn = New(codeCtlGRPCCreateConn, ClassDMCtl, ScopeInternal, LevelHigh, "can not create grpc connection", "Please check your network connection.") ErrCtlInvalidTLSCfg = New(codeCtlInvalidTLSCfg, ClassDMCtl, ScopeInternal, LevelMedium, "invalid TLS config", "Please check the `ssl-ca`, `ssl-cert` and `ssl-key` config in command line.") - // default error + // default error. ErrNotSet = New(codeNotSet, ClassNotSet, ScopeNotSet, LevelHigh, "", "") ) diff --git a/pkg/terror/terror.go b/pkg/terror/terror.go index 958de93e05..21cb4b24f4 100644 --- a/pkg/terror/terror.go +++ b/pkg/terror/terror.go @@ -27,10 +27,10 @@ const ( // ErrCode is used as the unique identifier of a specific error type. type ErrCode int -// ErrClass represents a class of errors +// ErrClass represents a class of errors. type ErrClass int -// Error classes +// Error classes. const ( ClassDatabase ErrClass = iota + 1 ClassFunctional @@ -75,7 +75,7 @@ var errClass2Str = map[ErrClass]string{ ClassNotSet: "not-set", } -// String implements fmt.Stringer interface +// String implements fmt.Stringer interface. func (ec ErrClass) String() string { if s, ok := errClass2Str[ec]; ok { return s @@ -87,7 +87,7 @@ func (ec ErrClass) String() string { // downstream DB error, DM internal error etc. type ErrScope int -// Error scopes +// Error scopes. const ( ScopeNotSet ErrScope = iota ScopeUpstream @@ -102,7 +102,7 @@ var errScope2Str = map[ErrScope]string{ ScopeInternal: "internal", } -// String implements fmt.Stringer interface +// String implements fmt.Stringer interface. func (es ErrScope) String() string { if s, ok := errScope2Str[es]; ok { return s @@ -110,10 +110,10 @@ func (es ErrScope) String() string { return fmt.Sprintf("unknown error scope: %d", es) } -// ErrLevel represents the emergency level of a specific error type +// ErrLevel represents the emergency level of a specific error type. type ErrLevel int -// Error levels +// Error levels. const ( LevelLow ErrLevel = iota + 1 LevelMedium @@ -126,7 +126,7 @@ var errLevel2Str = map[ErrLevel]string{ LevelHigh: "high", } -// String implements fmt.Stringer interface +// String implements fmt.Stringer interface. func (el ErrLevel) String() string { if s, ok := errLevel2Str[el]; ok { return s @@ -134,7 +134,7 @@ func (el ErrLevel) String() string { return fmt.Sprintf("unknown error level: %d", el) } -// Error implements error interface and add more useful fields +// Error implements error interface and add more useful fields. type Error struct { code ErrCode class ErrClass @@ -147,7 +147,7 @@ type Error struct { stack errors.StackTracer } -// New creates a new *Error instance +// New creates a new *Error instance. func New(code ErrCode, class ErrClass, scope ErrScope, level ErrLevel, message string, workaround string) *Error { return &Error{ code: code, @@ -159,22 +159,22 @@ func New(code ErrCode, class ErrClass, scope ErrScope, level ErrLevel, message s } } -// Code returns ErrCode +// Code returns ErrCode. func (e *Error) Code() ErrCode { return e.code } -// Class returns ErrClass +// Class returns ErrClass. func (e *Error) Class() ErrClass { return e.class } -// Scope returns ErrScope +// Scope returns ErrScope. func (e *Error) Scope() ErrScope { return e.scope } -// Level returns ErrLevel +// Level returns ErrLevel. func (e *Error) Level() ErrLevel { return e.level } @@ -184,7 +184,7 @@ func (e *Error) Message() string { return e.getMsg() } -// Workaround returns ErrWorkaround +// Workaround returns ErrWorkaround. func (e *Error) Workaround() string { return e.workaround } @@ -204,7 +204,7 @@ func (e *Error) Error() string { return str } -// Format accepts flags that alter the printing of some verbs +// Format accepts flags that alter the printing of some verbs. func (e *Error) Format(s fmt.State, verb rune) { switch verb { case 'v': @@ -226,7 +226,7 @@ func (e *Error) Format(s fmt.State, verb rune) { } // Cause implements causer.Cause defined in pingcap/errors -// and returns the raw cause of an *Error +// and returns the raw cause of an *Error. func (e *Error) Cause() error { return e.rawCause } @@ -247,7 +247,7 @@ func (e *Error) Equal(err error) bool { return ok && e.code == inErr.code } -// SetMessage clones an Error and resets its message +// SetMessage clones an Error and resets its message. func (e *Error) SetMessage(message string) *Error { err := *e err.message = message @@ -255,7 +255,7 @@ func (e *Error) SetMessage(message string) *Error { return &err } -// New generates a new *Error with the same class and code, and replace message with new message +// New generates a new *Error with the same class and code, and replace message with new message. func (e *Error) New(message string) error { return e.stackLevelGeneratef(1, message) } @@ -270,7 +270,7 @@ func (e *Error) Generatef(format string, args ...interface{}) error { return e.stackLevelGeneratef(1, format, args...) } -// stackLevelGeneratef is an inner interface to generate new *Error +// stackLevelGeneratef is an inner interface to generate new *Error. func (e *Error) stackLevelGeneratef(stackSkipLevel int, format string, args ...interface{}) error { return &Error{ code: e.code, @@ -285,7 +285,7 @@ func (e *Error) stackLevelGeneratef(stackSkipLevel int, format string, args ...i } // Delegate creates a new *Error with the same fields of the give *Error, -// except for new arguments, it also sets the err as raw cause of *Error +// except for new arguments, it also sets the err as raw cause of *Error. func (e *Error) Delegate(err error, args ...interface{}) error { if err == nil { return nil @@ -310,7 +310,7 @@ func (e *Error) Delegate(err error, args ...interface{}) error { } } -// AnnotateDelegate resets the message of *Error and Delegate with error and new args +// AnnotateDelegate resets the message of *Error and Delegate with error and new args. func (e *Error) AnnotateDelegate(err error, message string, args ...interface{}) error { if err == nil { return nil @@ -319,7 +319,7 @@ func (e *Error) AnnotateDelegate(err error, message string, args ...interface{}) } // Annotate tries to convert err to *Error and adds a message to it. -// This API is designed to reset Error message but keeps its original trace stack +// This API is designed to reset Error message but keeps its original trace stack. func Annotate(err error, message string) error { if err == nil { return nil @@ -347,7 +347,7 @@ func Annotatef(err error, format string, args ...interface{}) error { return e } -// Message returns `getMsg()` value if err is an *Error instance, else returns `Error()` value +// Message returns `getMsg()` value if err is an *Error instance, else returns `Error()` value. func Message(err error) string { if err == nil { return "" @@ -360,7 +360,7 @@ func Message(err error) string { } // WithScope tries to set given scope to *Error, if err is not an *Error instance, -// wrap it with error scope instead +// wrap it with error scope instead. func WithScope(err error, scope ErrScope) error { if err == nil { return nil @@ -374,7 +374,7 @@ func WithScope(err error, scope ErrScope) error { } // WithClass tries to set given class to *Error, if err is not an *Error instance, -// wrap it with error class instead +// wrap it with error class instead. func WithClass(err error, class ErrClass) error { if err == nil { return nil diff --git a/pkg/terror/terror_test.go b/pkg/terror/terror_test.go index 66ba493cc4..97614c54b9 100644 --- a/pkg/terror/terror_test.go +++ b/pkg/terror/terror_test.go @@ -29,8 +29,7 @@ func TestT(t *testing.T) { var _ = check.Suite(&testTErrorSuite{}) -type testTErrorSuite struct { -} +type testTErrorSuite struct{} func (t *testTErrorSuite) TestTError(c *check.C) { var ( diff --git a/pkg/upgrade/upgrade.go b/pkg/upgrade/upgrade.go index 148d2c4b46..f7ec65701f 100644 --- a/pkg/upgrade/upgrade.go +++ b/pkg/upgrade/upgrade.go @@ -32,17 +32,15 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -var ( - // upgrades records all functions used to upgrade from one version to the later version. - upgrades = []func(cli *clientv3.Client, uctx Context) error{ - upgradeToVer1, - upgradeToVer2, - upgradeToVer3, - } -) +// upgrades records all functions used to upgrade from one version to the later version. +var upgrades = []func(cli *clientv3.Client, uctx Context) error{ + upgradeToVer1, + upgradeToVer2, + upgradeToVer3, +} // Context is used to pass something to TryUpgrade -// NOTE that zero value of Context is nil, be aware of nil-dereference +// NOTE that zero value of Context is nil, be aware of nil-dereference. type Context struct { context.Context SubTaskConfigs map[string]map[string]config.SubTaskConfig @@ -99,7 +97,7 @@ func TryUpgrade(cli *clientv3.Client, uctx Context) error { } // UntouchVersionUpgrade runs all upgrade functions but doesn't change cluster version. This function is called when -// upgrade from v1.0, with a later PutVersion in caller after success +// upgrade from v1.0, with a later PutVersion in caller after success. func UntouchVersionUpgrade(cli *clientv3.Client, uctx Context) error { for _, upgrade := range upgrades { err := upgrade(cli, uctx) @@ -116,7 +114,7 @@ func upgradeToVer1(cli *clientv3.Client, uctx Context) error { return nil } -// upgradeToVer2 does upgrade operations from Ver1 to Ver2 (v2.0.0-GA) to upgrade syncer checkpoint schema +// upgradeToVer2 does upgrade operations from Ver1 to Ver2 (v2.0.0-GA) to upgrade syncer checkpoint schema. func upgradeToVer2(cli *clientv3.Client, uctx Context) error { upgradeTaskName := "upgradeToVer2" logger := log.L().WithFields(zap.String("task", upgradeTaskName)) @@ -149,7 +147,7 @@ func upgradeToVer2(cli *clientv3.Client, uctx Context) error { }() // 10 seconds for each subtask - timeout := time.Duration(len(dbConfigs)) * 10 * time.Second + timeout := time.Duration(len(dbConfigs)*10) * time.Second upgradeCtx, cancel := context.WithTimeout(context.Background(), timeout) uctx.Context = upgradeCtx defer cancel() @@ -184,7 +182,7 @@ func upgradeToVer2(cli *clientv3.Client, uctx Context) error { return nil } -// upgradeToVer3 does upgrade operations from Ver2 (v2.0.0-GA) to Ver3 (v2.0.2) to upgrade etcd key encodings +// upgradeToVer3 does upgrade operations from Ver2 (v2.0.0-GA) to Ver3 (v2.0.2) to upgrade etcd key encodings. func upgradeToVer3(cli *clientv3.Client, uctx Context) error { upgradeCtx, cancel := context.WithTimeout(context.Background(), time.Minute) uctx.Context = upgradeCtx @@ -204,7 +202,7 @@ func upgradeToVer3(cli *clientv3.Client, uctx Context) error { }, } - var ops []clientv3.Op + ops := make([]clientv3.Op, 0, len(etcdKeyUpgrades)) for _, pair := range etcdKeyUpgrades { resp, err := cli.Get(uctx.Context, pair.old.Path(), clientv3.WithPrefix()) if err != nil { diff --git a/pkg/upgrade/upgrade_test.go b/pkg/upgrade/upgrade_test.go index e8ffee772c..a423a85c0a 100644 --- a/pkg/upgrade/upgrade_test.go +++ b/pkg/upgrade/upgrade_test.go @@ -24,9 +24,7 @@ import ( "github.com/pingcap/dm/dm/common" ) -var ( - etcdTestCli *clientv3.Client -) +var etcdTestCli *clientv3.Client func TestUpgrade(t *testing.T) { mockCluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) diff --git a/pkg/utils/common.go b/pkg/utils/common.go index d24d2997df..f7b0ffa9da 100644 --- a/pkg/utils/common.go +++ b/pkg/utils/common.go @@ -45,7 +45,7 @@ func TrimCtrlChars(s string) string { } // TrimQuoteMark tries to trim leading and tailing quote(") mark if exists -// only trim if leading and tailing quote matched as a pair +// only trim if leading and tailing quote matched as a pair. func TrimQuoteMark(s string) string { if len(s) > 2 && s[0] == '"' && s[len(s)-1] == '"' { return s[1 : len(s)-1] @@ -53,7 +53,7 @@ func TrimQuoteMark(s string) string { return s } -// FetchAllDoTables returns all need to do tables after filtered (fetches from upstream MySQL) +// FetchAllDoTables returns all need to do tables after filtered (fetches from upstream MySQL). func FetchAllDoTables(ctx context.Context, db *sql.DB, bw *filter.Filter) (map[string][]string, error) { schemas, err := dbutil.GetSchemas(ctx, db) @@ -112,7 +112,7 @@ func FetchAllDoTables(ctx context.Context, db *sql.DB, bw *filter.Filter) (map[s return schemaToTables, nil } -// FetchTargetDoTables returns all need to do tables after filtered and routed (fetches from upstream MySQL) +// FetchTargetDoTables returns all need to do tables after filtered and routed (fetches from upstream MySQL). func FetchTargetDoTables(ctx context.Context, db *sql.DB, bw *filter.Filter, router *router.Table) (map[string][]*filter.Table, error) { // fetch tables from source and filter them sourceTables, err := FetchAllDoTables(ctx, db, bw) @@ -146,7 +146,7 @@ func FetchTargetDoTables(ctx context.Context, db *sql.DB, bw *filter.Filter, rou } // CompareShardingDDLs compares s and t ddls -// only concern in content, ignore order of ddl +// only concern in content, ignore order of ddl. func CompareShardingDDLs(s, t []string) bool { if len(s) != len(t) { return false @@ -166,12 +166,12 @@ func CompareShardingDDLs(s, t []string) bool { return true } -// GenDDLLockID returns lock ID used in shard-DDL +// GenDDLLockID returns lock ID used in shard-DDL. func GenDDLLockID(task, schema, table string) string { return fmt.Sprintf("%s-%s", task, dbutil.TableName(schema, table)) } -// ExtractTaskFromLockID extract task from lockID +// ExtractTaskFromLockID extract task from lockID. func ExtractTaskFromLockID(lockID string) string { pattern := regexp.MustCompile("(.*)\\-\\`(.*)\\`.\\`(.*)\\`") strs := pattern.FindStringSubmatch(lockID) @@ -182,7 +182,7 @@ func ExtractTaskFromLockID(lockID string) string { return strs[1] } -// NonRepeatStringsEqual is used to compare two un-ordered, non-repeat-element string slice is equal +// NonRepeatStringsEqual is used to compare two un-ordered, non-repeat-element string slice is equal. func NonRepeatStringsEqual(a, b []string) bool { if len(a) != len(b) { return false diff --git a/pkg/utils/common_test.go b/pkg/utils/common_test.go index 89225e0ff4..5b2b8de634 100644 --- a/pkg/utils/common_test.go +++ b/pkg/utils/common_test.go @@ -27,8 +27,7 @@ import ( var _ = Suite(&testCommonSuite{}) -type testCommonSuite struct { -} +type testCommonSuite struct{} func (s *testCommonSuite) TestTrimCtrlChars(c *C) { ddl := "create table if not exists foo.bar(id int)" diff --git a/pkg/utils/db.go b/pkg/utils/db.go index 7ae0b63ef4..421f5c6eb1 100644 --- a/pkg/utils/db.go +++ b/pkg/utils/db.go @@ -43,14 +43,14 @@ const ( // DefaultDBTimeout represents a DB operation timeout for common usages. DefaultDBTimeout = 30 * time.Second - // for MariaDB, UUID set as `gtid_domain_id` + domainServerIDSeparator + `server_id` + // for MariaDB, UUID set as `gtid_domain_id` + domainServerIDSeparator + `server_id`. domainServerIDSeparator = "-" - // the default base(min) server id generated by random + // the default base(min) server id generated by random. defaultBaseServerID = math.MaxUint32 / 10 ) -// GetFlavor gets flavor from DB +// GetFlavor gets flavor from DB. func GetFlavor(ctx context.Context, db *sql.DB) (string, error) { value, err := dbutil.ShowVersion(ctx, db) if err != nil { @@ -62,7 +62,7 @@ func GetFlavor(ctx context.Context, db *sql.DB) (string, error) { return gmysql.MySQLFlavor, nil } -// GetAllServerID gets all slave server id and master server id +// GetAllServerID gets all slave server id and master server id. func GetAllServerID(ctx context.Context, db *sql.DB) (map[uint32]struct{}, error) { serverIDs, err := GetSlaveServerID(ctx, db) if err != nil { @@ -78,7 +78,7 @@ func GetAllServerID(ctx context.Context, db *sql.DB) (map[uint32]struct{}, error return serverIDs, nil } -// GetRandomServerID gets a random server ID which is not used +// GetRandomServerID gets a random server ID which is not used. func GetRandomServerID(ctx context.Context, db *sql.DB) (uint32, error) { rand.Seed(time.Now().UnixNano()) @@ -101,7 +101,7 @@ func GetRandomServerID(ctx context.Context, db *sql.DB) (uint32, error) { return 0, terror.ErrInvalidServerID.Generatef("can't find a random available server ID") } -// GetSlaveServerID gets all slave server id +// GetSlaveServerID gets all slave server id. func GetSlaveServerID(ctx context.Context, db *sql.DB) (map[uint32]struct{}, error) { rows, err := db.QueryContext(ctx, `SHOW SLAVE HOSTS`) if err != nil { @@ -168,7 +168,7 @@ func GetSlaveServerID(ctx context.Context, db *sql.DB) (map[uint32]struct{}, err return serverIDs, nil } -// GetMasterStatus gets status from master +// GetMasterStatus gets status from master. func GetMasterStatus(ctx context.Context, db *sql.DB, flavor string) (gmysql.Position, gtid.Set, error) { var ( binlogPos gmysql.Position @@ -236,7 +236,7 @@ func GetMasterStatus(ctx context.Context, db *sql.DB, flavor string) (gmysql.Pos } // GetMariaDBGTID gets MariaDB's `gtid_binlog_pos` -// it can not get by `SHOW MASTER STATUS` +// it can not get by `SHOW MASTER STATUS`. func GetMariaDBGTID(ctx context.Context, db *sql.DB) (gtid.Set, error) { gtidStr, err := GetGlobalVariable(ctx, db, "gtid_binlog_pos") if err != nil { @@ -249,7 +249,7 @@ func GetMariaDBGTID(ctx context.Context, db *sql.DB) (gtid.Set, error) { return gs, nil } -// GetGlobalVariable gets server's global variable +// GetGlobalVariable gets server's global variable. func GetGlobalVariable(ctx context.Context, db *sql.DB, variable string) (value string, err error) { failpoint.Inject("GetGlobalVariableFailed", func(val failpoint.Value) { items := strings.Split(val.(string), ",") @@ -276,7 +276,7 @@ func GetGlobalVariable(ctx context.Context, db *sql.DB, variable string) (value return getVariable(ctx, conn, variable, true) } -// GetSessionVariable gets connection's session variable +// GetSessionVariable gets connection's session variable. func GetSessionVariable(ctx context.Context, conn *sql.Conn, variable string) (value string, err error) { failpoint.Inject("GetSessionVariableFailed", func(val failpoint.Value) { items := strings.Split(val.(string), ",") @@ -324,7 +324,7 @@ func getVariable(ctx context.Context, conn *sql.Conn, variable string, isGlobal return value, nil } -// GetServerID gets server's `server_id` +// GetServerID gets server's `server_id`. func GetServerID(ctx context.Context, db *sql.DB) (uint32, error) { serverIDStr, err := GetGlobalVariable(ctx, db, "server_id") if err != nil { @@ -335,7 +335,7 @@ func GetServerID(ctx context.Context, db *sql.DB) (uint32, error) { return uint32(serverID), terror.ErrInvalidServerID.Delegate(err, serverIDStr) } -// GetMariaDBGtidDomainID gets MariaDB server's `gtid_domain_id` +// GetMariaDBGtidDomainID gets MariaDB server's `gtid_domain_id`. func GetMariaDBGtidDomainID(ctx context.Context, db *sql.DB) (uint32, error) { domainIDStr, err := GetGlobalVariable(ctx, db, "gtid_domain_id") if err != nil { @@ -346,7 +346,7 @@ func GetMariaDBGtidDomainID(ctx context.Context, db *sql.DB) (uint32, error) { return uint32(domainID), terror.ErrMariaDBDomainID.Delegate(err, domainIDStr) } -// GetServerUUID gets server's `server_uuid` +// GetServerUUID gets server's `server_uuid`. func GetServerUUID(ctx context.Context, db *sql.DB, flavor string) (string, error) { if flavor == gmysql.MariaDBFlavor { return GetMariaDBUUID(ctx, db) @@ -356,7 +356,7 @@ func GetServerUUID(ctx context.Context, db *sql.DB, flavor string) (string, erro } // GetMariaDBUUID gets equivalent `server_uuid` for MariaDB -// `gtid_domain_id` joined `server_id` with domainServerIDSeparator +// `gtid_domain_id` joined `server_id` with domainServerIDSeparator. func GetMariaDBUUID(ctx context.Context, db *sql.DB) (string, error) { domainID, err := GetMariaDBGtidDomainID(ctx, db) if err != nil { @@ -369,7 +369,7 @@ func GetMariaDBUUID(ctx context.Context, db *sql.DB) (string, error) { return fmt.Sprintf("%d%s%d", domainID, domainServerIDSeparator, serverID), nil } -// GetParser gets a parser for sql.DB which is suitable for session variable sql_mode +// GetParser gets a parser for sql.DB which is suitable for session variable sql_mode. func GetParser(ctx context.Context, db *sql.DB) (*parser.Parser, error) { c, err := db.Conn(ctx) if err != nil { @@ -379,7 +379,7 @@ func GetParser(ctx context.Context, db *sql.DB) (*parser.Parser, error) { return GetParserForConn(ctx, c) } -// GetParserForConn gets a parser for sql.Conn which is suitable for session variable sql_mode +// GetParserForConn gets a parser for sql.Conn which is suitable for session variable sql_mode. func GetParserForConn(ctx context.Context, conn *sql.Conn) (*parser.Parser, error) { sqlMode, err := GetSessionVariable(ctx, conn, "sql_mode") if err != nil { @@ -388,7 +388,7 @@ func GetParserForConn(ctx context.Context, conn *sql.Conn) (*parser.Parser, erro return GetParserFromSQLModeStr(sqlMode) } -// GetParserFromSQLModeStr gets a parser and applies given sqlMode +// GetParserFromSQLModeStr gets a parser and applies given sqlMode. func GetParserFromSQLModeStr(sqlMode string) (*parser.Parser, error) { mode, err := tmysql.GetSQLMode(sqlMode) if err != nil { @@ -400,30 +400,30 @@ func GetParserFromSQLModeStr(sqlMode string) (*parser.Parser, error) { return parser2, nil } -// KillConn kills the DB connection (thread in mysqld) +// KillConn kills the DB connection (thread in mysqld). func KillConn(ctx context.Context, db *sql.DB, connID uint32) error { _, err := db.ExecContext(ctx, fmt.Sprintf("KILL %d", connID)) return terror.DBErrorAdapt(err, terror.ErrDBDriverError) } -// IsMySQLError checks whether err is MySQLError error +// IsMySQLError checks whether err is MySQLError error. func IsMySQLError(err error, code uint16) bool { err = errors.Cause(err) e, ok := err.(*mysql.MySQLError) return ok && e.Number == code } -// IsErrBinlogPurged checks whether err is BinlogPurged error +// IsErrBinlogPurged checks whether err is BinlogPurged error. func IsErrBinlogPurged(err error) bool { return IsMySQLError(err, tmysql.ErrMasterFatalErrorReadingBinlog) } -// IsNoSuchThreadError checks whether err is NoSuchThreadError +// IsNoSuchThreadError checks whether err is NoSuchThreadError. func IsNoSuchThreadError(err error) bool { return IsMySQLError(err, tmysql.ErrNoSuchThread) } -// GetGTIDMode return GTID_MODE +// GetGTIDMode return GTID_MODE. func GetGTIDMode(ctx context.Context, db *sql.DB) (string, error) { val, err := GetGlobalVariable(ctx, db, "GTID_MODE") return val, err diff --git a/pkg/utils/db_test.go b/pkg/utils/db_test.go index 8c9c02370f..a09b479388 100644 --- a/pkg/utils/db_test.go +++ b/pkg/utils/db_test.go @@ -28,8 +28,7 @@ import ( var _ = Suite(&testDBSuite{}) -type testDBSuite struct { -} +type testDBSuite struct{} func (t *testDBSuite) TestGetFlavor(c *C) { db, mock, err := sqlmock.New() @@ -286,7 +285,6 @@ func (t *testDBSuite) createMockResult(mock sqlmock.Sqlmock, masterID uint32, se rows.AddRow(serverID, host, port, masterID) } expectQuery.WillReturnRows(rows) - } else { rows := sqlmock.NewRows([]string{"Server_id", "Host", "Port", "Master_id", "Slave_UUID"}) for _, serverID := range serverIDs { diff --git a/pkg/utils/encrypt.go b/pkg/utils/encrypt.go index 8205d7d2b4..bd7d72ea42 100644 --- a/pkg/utils/encrypt.go +++ b/pkg/utils/encrypt.go @@ -20,7 +20,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// Encrypt tries to encrypt plaintext to base64 encoded ciphertext +// Encrypt tries to encrypt plaintext to base64 encoded ciphertext. func Encrypt(plaintext string) (string, error) { ciphertext, err := encrypt.Encrypt([]byte(plaintext)) if err != nil { @@ -30,7 +30,7 @@ func Encrypt(plaintext string) (string, error) { return base64.StdEncoding.EncodeToString(ciphertext), nil } -// Decrypt tries to decrypt base64 encoded ciphertext to plaintext +// Decrypt tries to decrypt base64 encoded ciphertext to plaintext. func Decrypt(ciphertextB64 string) (string, error) { ciphertext, err := base64.StdEncoding.DecodeString(ciphertextB64) if err != nil { @@ -44,7 +44,7 @@ func Decrypt(ciphertextB64 string) (string, error) { return string(plaintext), nil } -// DecryptOrPlaintext tries to decrypt base64 encoded ciphertext to plaintext or return plaintext +// DecryptOrPlaintext tries to decrypt base64 encoded ciphertext to plaintext or return plaintext. func DecryptOrPlaintext(ciphertextB64 string) string { plaintext, err := Decrypt(ciphertextB64) if err != nil { diff --git a/pkg/utils/encrypt_test.go b/pkg/utils/encrypt_test.go index eeea3ee5cf..a27db2f709 100644 --- a/pkg/utils/encrypt_test.go +++ b/pkg/utils/encrypt_test.go @@ -23,8 +23,7 @@ import ( var _ = Suite(&testEncryptSuite{}) -type testEncryptSuite struct { -} +type testEncryptSuite struct{} func (t *testEncryptSuite) TestEncrypt(c *C) { plaintext := "abc@123" diff --git a/pkg/utils/file_test.go b/pkg/utils/file_test.go index 7519f0f308..59ee6723a8 100644 --- a/pkg/utils/file_test.go +++ b/pkg/utils/file_test.go @@ -24,8 +24,7 @@ import ( var _ = Suite(&testFileSuite{}) -type testFileSuite struct { -} +type testFileSuite struct{} func (t *testFileSuite) TestFile(c *C) { // dir not exists @@ -52,7 +51,7 @@ func (t *testFileSuite) TestFile(c *C) { c.Assert(size, Equals, int64(0)) // create a file - c.Assert(ioutil.WriteFile(f, []byte("some content"), 0644), IsNil) + c.Assert(ioutil.WriteFile(f, []byte("some content"), 0o644), IsNil) c.Assert(IsFileExists(f), IsTrue) c.Assert(IsDirExists(f), IsFalse) size, err = GetFileSize(f) diff --git a/pkg/utils/hash.go b/pkg/utils/hash.go index 4f6c0d55a2..e09cc0c538 100644 --- a/pkg/utils/hash.go +++ b/pkg/utils/hash.go @@ -17,7 +17,7 @@ import ( "hash/crc32" ) -// GenHashKey generates key with crc32 algorithm +// GenHashKey generates key with crc32 algorithm. func GenHashKey(key string) uint32 { return crc32.ChecksumIEEE([]byte(key)) } diff --git a/pkg/utils/hash_test.go b/pkg/utils/hash_test.go index e1cf2ba289..434b2fb297 100644 --- a/pkg/utils/hash_test.go +++ b/pkg/utils/hash_test.go @@ -19,8 +19,7 @@ import ( var _ = Suite(&testHashSuite{}) -type testHashSuite struct { -} +type testHashSuite struct{} func (t *testHashSuite) TestHash(c *C) { // we only ensure hash multiple times for the same key got the same hash now. diff --git a/pkg/utils/printer.go b/pkg/utils/printer.go index 73142d2d1e..0c2345226c 100644 --- a/pkg/utils/printer.go +++ b/pkg/utils/printer.go @@ -31,7 +31,7 @@ var ( GoVersion = "None" ) -// GetRawInfo do what its name tells +// GetRawInfo do what its name tells. func GetRawInfo() string { var info string info += fmt.Sprintf("Release Version: %s\n", ReleaseVersion) @@ -60,7 +60,7 @@ func printInfo(app string) { ) } -// PrintInfo2 print app's info to stdout +// PrintInfo2 print app's info to stdout. func PrintInfo2(app string) { fmt.Printf("Welcome to %s\n", app) fmt.Printf("Release Version: %s\n", ReleaseVersion) diff --git a/pkg/utils/printer_test.go b/pkg/utils/printer_test.go index 5b89c258a9..0c96205af4 100644 --- a/pkg/utils/printer_test.go +++ b/pkg/utils/printer_test.go @@ -22,8 +22,7 @@ import ( var _ = Suite(&testPrinterSuite{}) -type testPrinterSuite struct { -} +type testPrinterSuite struct{} func (t *testPrinterSuite) SetUpTest(c *C) { c.Assert(log.InitLogger(&log.Config{}), IsNil) diff --git a/pkg/utils/relay.go b/pkg/utils/relay.go index 2f0528932e..39483ab57d 100644 --- a/pkg/utils/relay.go +++ b/pkg/utils/relay.go @@ -27,14 +27,14 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// not support to config yet +// not support to config yet. var ( UUIDIndexFilename = "server-uuid.index" MetaFilename = "relay.meta" uuidIndexSeparator = "." ) -// ParseUUIDIndex parses server-uuid.index +// ParseUUIDIndex parses server-uuid.index. func ParseUUIDIndex(indexPath string) ([]string, error) { fd, err := os.Open(indexPath) if os.IsNotExist(err) { @@ -67,17 +67,17 @@ func ParseUUIDIndex(indexPath string) ([]string, error) { return uuids, nil } -// AddSuffixForUUID adds a suffix for UUID -func AddSuffixForUUID(uuid string, ID int) string { - return fmt.Sprintf("%s%s%06d", uuid, uuidIndexSeparator, ID) // eg. 53ea0ed1-9bf8-11e6-8bea-64006a897c73.000001 +// AddSuffixForUUID adds a suffix for UUID. +func AddSuffixForUUID(uuid string, id int) string { + return fmt.Sprintf("%s%s%06d", uuid, uuidIndexSeparator, id) // eg. 53ea0ed1-9bf8-11e6-8bea-64006a897c73.000001 } -// SuffixIntToStr convert int-represented suffix to string-represented -func SuffixIntToStr(ID int) string { - return fmt.Sprintf("%06d", ID) +// SuffixIntToStr convert int-represented suffix to string-represented. +func SuffixIntToStr(id int) string { + return fmt.Sprintf("%06d", id) } -// ParseSuffixForUUID parses UUID (with suffix) to (UUID without suffix, suffix) pair +// ParseSuffixForUUID parses UUID (with suffix) to (UUID without suffix, suffix) pair. func ParseSuffixForUUID(uuid string) (string, int, error) { parts := strings.Split(uuid, uuidIndexSeparator) if len(parts) != 2 || len(parts[1]) != 6 { @@ -91,7 +91,7 @@ func ParseSuffixForUUID(uuid string) (string, int, error) { } // GetSuffixUUID gets UUID (with suffix) by UUID (without suffix) -// when multi UUIDs (without suffix) are the same, the newest will be return +// when multi UUIDs (without suffix) are the same, the newest will be return. func GetSuffixUUID(indexPath, uuid string) (string, error) { uuids, err := ParseUUIDIndex(indexPath) if err != nil { @@ -112,7 +112,7 @@ func GetSuffixUUID(indexPath, uuid string) (string, error) { return "", terror.ErrRelayUUIDWithSuffixNotFound.Generate(uuid, indexPath, uuids) } -// GetUUIDBySuffix gets UUID from uuids by suffix +// GetUUIDBySuffix gets UUID from uuids by suffix. func GetUUIDBySuffix(uuids []string, suffix string) string { suffix2 := fmt.Sprintf("%s%s", uuidIndexSeparator, suffix) for _, uuid := range uuids { diff --git a/pkg/utils/relay_test.go b/pkg/utils/relay_test.go index 545927b0bd..a8262fa1a7 100644 --- a/pkg/utils/relay_test.go +++ b/pkg/utils/relay_test.go @@ -29,8 +29,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testUtilsSuite struct { -} +type testUtilsSuite struct{} func (t *testUtilsSuite) TestParseUUIDIndex(c *C) { f, err := ioutil.TempFile("", "server-uuid.index") @@ -43,7 +42,7 @@ func (t *testUtilsSuite) TestParseUUIDIndex(c *C) { "c65525fa-c7a3-11e8-a878-0242ac130005.000003", } - err = ioutil.WriteFile(f.Name(), []byte(strings.Join(uuids, "\n")), 0644) + err = ioutil.WriteFile(f.Name(), []byte(strings.Join(uuids, "\n")), 0o644) c.Assert(err, IsNil) obtainedUUIDs, err := ParseUUIDIndex(f.Name()) diff --git a/pkg/utils/storage_test.go b/pkg/utils/storage_test.go index 0029768ada..1bf15d05b0 100644 --- a/pkg/utils/storage_test.go +++ b/pkg/utils/storage_test.go @@ -19,8 +19,7 @@ import ( var _ = Suite(&testStorageSuite{}) -type testStorageSuite struct { -} +type testStorageSuite struct{} func (t *testStorageSuite) TestGetStorageSize(c *C) { // only ensure we can get storage size. diff --git a/pkg/utils/storage_unix.go b/pkg/utils/storage_unix.go index 7c1a723c4c..cc79384377 100644 --- a/pkg/utils/storage_unix.go +++ b/pkg/utils/storage_unix.go @@ -23,7 +23,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// GetStorageSize gets storage's capacity and available size +// GetStorageSize gets storage's capacity and available size. func GetStorageSize(dir string) (size StorageSize, err error) { var stat unix.Statfs_t diff --git a/pkg/utils/string_test.go b/pkg/utils/string_test.go index f927020b8c..12c946cdeb 100644 --- a/pkg/utils/string_test.go +++ b/pkg/utils/string_test.go @@ -19,8 +19,7 @@ import ( var _ = Suite(&testStringSuite{}) -type testStringSuite struct { -} +type testStringSuite struct{} func (t *testStringSuite) TestTruncateString(c *C) { cases := []struct { diff --git a/pkg/utils/util.go b/pkg/utils/util.go index 57ec74944c..a132b5468c 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -32,7 +32,7 @@ import ( ) var ( - // OsExit is function placeholder for os.Exit + // OsExit is function placeholder for os.Exit. OsExit func(int) /* CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name @@ -107,7 +107,7 @@ func init() { pb.HidePwdFunc = HidePassword } -// DecodeBinlogPosition parses a mysql.Position from string format +// DecodeBinlogPosition parses a mysql.Position from string format. func DecodeBinlogPosition(pos string) (*mysql.Position, error) { if len(pos) < 3 { return nil, terror.ErrInvalidBinlogPosStr.Generate(pos) @@ -164,12 +164,12 @@ func WaitSomething(backoff int, waitTime time.Duration, fn func() bool) bool { return false } -// IsContextCanceledError checks whether err is context.Canceled +// IsContextCanceledError checks whether err is context.Canceled. func IsContextCanceledError(err error) bool { return errors.Cause(err) == context.Canceled } -// IgnoreErrorCheckpoint is used in checkpoint update +// IgnoreErrorCheckpoint is used in checkpoint update. func IgnoreErrorCheckpoint(err error) bool { err = errors.Cause(err) // check the original error mysqlErr, ok := err.(*gmysql.MySQLError) @@ -185,18 +185,18 @@ func IgnoreErrorCheckpoint(err error) bool { } } -// IsBuildInSkipDDL return true when checked sql that will be skipped for syncer +// IsBuildInSkipDDL return true when checked sql that will be skipped for syncer. func IsBuildInSkipDDL(sql string) bool { return builtInSkipDDLPatterns.FindStringIndex(sql) != nil } -// HidePassword replace password with ****** +// HidePassword replace password with ******. func HidePassword(input string) string { output := passwordRegexp.ReplaceAllString(input, "$1******$4") return output } -// UnwrapScheme removes http or https scheme from input +// UnwrapScheme removes http or https scheme from input. func UnwrapScheme(s string) string { if strings.HasPrefix(s, "http://") { return s[len("http://"):] @@ -227,7 +227,7 @@ func WrapSchemes(s string, https bool) string { return strings.Join(output, ",") } -// WrapSchemesForInitialCluster acts like WrapSchemes, except input is "name=URL,..." +// WrapSchemesForInitialCluster acts like WrapSchemes, except input is "name=URL,...". func WrapSchemesForInitialCluster(s string, https bool) string { items := strings.Split(s, ",") output := make([]string, 0, len(items)) diff --git a/pkg/utils/util_test.go b/pkg/utils/util_test.go index 825d6f0e87..f47c8cb9f9 100644 --- a/pkg/utils/util_test.go +++ b/pkg/utils/util_test.go @@ -145,7 +145,6 @@ func (t *testUtilsSuite) TestCompareBinlogPos(c *C) { cmp := CompareBinlogPos(tc.pos1, tc.pos2, tc.deviation) c.Assert(cmp, Equals, tc.cmp) } - } func (t *testUtilsSuite) TestWaitSomething(c *C) { diff --git a/pkg/v1dbschema/schema_test.go b/pkg/v1dbschema/schema_test.go index a5ced3cafd..08ddbca430 100644 --- a/pkg/v1dbschema/schema_test.go +++ b/pkg/v1dbschema/schema_test.go @@ -179,7 +179,7 @@ func (t *testSchema) TestSchemaV106ToV20x(c *C) { c.Assert(rows.Scan(&count), IsNil) c.Assert(rows.Next(), IsFalse) c.Assert(rows.Err(), IsNil) - rows.Close() + defer rows.Close() c.Assert(count, Equals, 2) // verify the column data of checkpoint not updated. @@ -191,7 +191,7 @@ func (t *testSchema) TestSchemaV106ToV20x(c *C) { c.Assert(gs.Valid, IsFalse) } c.Assert(rows.Err(), IsNil) - rows.Close() + defer rows.Close() // update schema with GTID enabled. cfg.EnableGTID = true @@ -205,7 +205,7 @@ func (t *testSchema) TestSchemaV106ToV20x(c *C) { c.Assert(rows.Scan(&gs), IsNil) c.Assert(rows.Next(), IsFalse) c.Assert(rows.Err(), IsNil) - rows.Close() + defer rows.Close() c.Assert(gs.String, Equals, endGS.String()) rows, err = dbConn.QuerySQL(tctx, fmt.Sprintf(`SELECT binlog_gtid FROM %s WHERE is_global!=1`, dbutil.TableName(cfg.MetaSchema, cputil.SyncerCheckpoint(cfg.Name)))) @@ -216,5 +216,5 @@ func (t *testSchema) TestSchemaV106ToV20x(c *C) { c.Assert(gs.Valid, IsFalse) } c.Assert(rows.Err(), IsNil) - rows.Close() + defer rows.Close() } diff --git a/pkg/v1workermeta/api_test.go b/pkg/v1workermeta/api_test.go index 9c0065fb35..579ef1f563 100644 --- a/pkg/v1workermeta/api_test.go +++ b/pkg/v1workermeta/api_test.go @@ -32,6 +32,7 @@ type testAPI struct{} var _ = Suite(&testAPI{}) func (t *testAPI) TestAPI(c *C) { + // nolint:dogsled _, currFile, _, _ := runtime.Caller(0) srcMetaPath := filepath.Join(filepath.Dir(currFile), "v106_data_for_test") srcDBPath := filepath.Join(srcMetaPath, "kv") @@ -96,7 +97,7 @@ func (t *testAPI) TestAPI(c *C) { // remove an invalid meta path. metaPath = c.MkDir() dbPath = filepath.Join(metaPath, "kv") - c.Assert(os.Mkdir(dbPath, 0644), IsNil) + c.Assert(os.Mkdir(dbPath, 0o644), IsNil) c.Assert(terror.ErrInvalidV1WorkerMetaPath.Equal(RemoveSubtasksMeta()), IsTrue) } diff --git a/pkg/v1workermeta/db.go b/pkg/v1workermeta/db.go index c3d64c2f69..45636fb8e6 100644 --- a/pkg/v1workermeta/db.go +++ b/pkg/v1workermeta/db.go @@ -20,7 +20,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// kvConfig is the configuration of goleveldb +// kvConfig is the configuration of goleveldb. type kvConfig struct { BlockCacheCapacity int `toml:"block-cache-capacity" json:"block-cache-capacity"` BlockRestartInterval int `toml:"block-restart-interval" json:"block-restart-interval"` @@ -34,7 +34,7 @@ type kvConfig struct { WriteL0SlowdownTrigger int `toml:"write-L0-slowdown-trigger" json:"write-L0-slowdown-trigger"` } -// default leveldb config +// default leveldb config. var defaultKVConfig = &kvConfig{ BlockCacheCapacity: 8388608, BlockRestartInterval: 16, diff --git a/relay/common/util.go b/relay/common/util.go index a8b8ebbe7c..241c0f6ad2 100644 --- a/relay/common/util.go +++ b/relay/common/util.go @@ -21,7 +21,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// CheckIsDDL checks input SQL whether is a valid DDL statement +// CheckIsDDL checks input SQL whether is a valid DDL statement. func CheckIsDDL(sql string, p *parser.Parser) bool { sql = utils.TrimCtrlChars(sql) diff --git a/relay/common/util_test.go b/relay/common/util_test.go index b996a7e13b..a4e11aa1c6 100644 --- a/relay/common/util_test.go +++ b/relay/common/util_test.go @@ -24,12 +24,9 @@ func TestSuite(t *testing.T) { check.TestingT(t) } -var ( - _ = check.Suite(&testUtilSuite{}) -) +var _ = check.Suite(&testUtilSuite{}) -type testUtilSuite struct { -} +type testUtilSuite struct{} func (t *testUtilSuite) TestCheckIsDDL(c *check.C) { var ( diff --git a/relay/config.go b/relay/config.go index 63b150329d..24f981638b 100644 --- a/relay/config.go +++ b/relay/config.go @@ -49,7 +49,7 @@ func (c *Config) String() string { return string(cfg) } -// FromSourceCfg gen relay config from source config +// FromSourceCfg gen relay config from source config. func FromSourceCfg(sourceCfg *config.SourceConfig) *Config { clone := sourceCfg.DecryptPassword() cfg := &Config{ diff --git a/relay/meta.go b/relay/meta.go index e525ec13db..80e65cdfb6 100644 --- a/relay/meta.go +++ b/relay/meta.go @@ -38,7 +38,7 @@ var ( // Meta represents binlog meta information for sync source // when re-syncing, we should reload meta info to guarantee continuous transmission // in order to support master-slave switching, Meta should support switching binlog meta info to newer master -// should support the case, where switching from A to B, then switching from B back to A +// should support the case, where switching from A to B, then switching from B back to A. type Meta interface { // Load loads meta information for the recently active server Load() error @@ -86,7 +86,7 @@ type Meta interface { String() string } -// LocalMeta implements Meta by save info in local +// LocalMeta implements Meta by save info in local. type LocalMeta struct { sync.RWMutex flavor string @@ -103,7 +103,7 @@ type LocalMeta struct { BinlogGTID string `toml:"binlog-gtid" json:"binlog-gtid"` } -// NewLocalMeta creates a new LocalMeta +// NewLocalMeta creates a new LocalMeta. func NewLocalMeta(flavor, baseDir string) Meta { lm := &LocalMeta{ flavor: flavor, @@ -120,7 +120,7 @@ func NewLocalMeta(flavor, baseDir string) Meta { return lm } -// Load implements Meta.Load +// Load implements Meta.Load. func (lm *LocalMeta) Load() error { lm.Lock() defer lm.Unlock() @@ -152,7 +152,7 @@ func (lm *LocalMeta) Load() error { return nil } -// AdjustWithStartPos implements Meta.AdjustWithStartPos, return whether adjusted +// AdjustWithStartPos implements Meta.AdjustWithStartPos, return whether adjusted. func (lm *LocalMeta) AdjustWithStartPos(binlogName string, binlogGTID string, enableGTID bool, latestBinlogName string, latestBinlogGTID string) (bool, error) { lm.Lock() defer lm.Unlock() @@ -166,7 +166,7 @@ func (lm *LocalMeta) AdjustWithStartPos(binlogName string, binlogGTID string, en } } - var gset = lm.emptyGSet.Clone() + gset := lm.emptyGSet.Clone() var err error if enableGTID { @@ -182,10 +182,8 @@ func (lm *LocalMeta) AdjustWithStartPos(binlogName string, binlogGTID string, en if len(binlogName) == 0 { // no meaningful start pos specified binlogGTID = latestBinlogGTID binlogName = latestBinlogName - } else { - if !binlog.VerifyFilename(binlogName) { - return false, terror.ErrRelayBinlogNameNotValid.Generate(binlogName) - } + } else if !binlog.VerifyFilename(binlogName) { + return false, terror.ErrRelayBinlogNameNotValid.Generate(binlogName) } } @@ -197,7 +195,7 @@ func (lm *LocalMeta) AdjustWithStartPos(binlogName string, binlogGTID string, en return true, lm.doFlush() } -// Save implements Meta.Save +// Save implements Meta.Save. func (lm *LocalMeta) Save(pos mysql.Position, gset gtid.Set) error { lm.Lock() defer lm.Unlock() @@ -220,7 +218,7 @@ func (lm *LocalMeta) Save(pos mysql.Position, gset gtid.Set) error { return nil } -// Flush implements Meta.Flush +// Flush implements Meta.Flush. func (lm *LocalMeta) Flush() error { lm.Lock() defer lm.Unlock() @@ -228,7 +226,7 @@ func (lm *LocalMeta) Flush() error { return lm.doFlush() } -// doFlush does the real flushing +// doFlush does the real flushing. func (lm *LocalMeta) doFlush() error { if len(lm.currentUUID) == 0 { return terror.ErrRelayNoCurrentUUID.Generate() @@ -242,7 +240,7 @@ func (lm *LocalMeta) doFlush() error { } filename := filepath.Join(lm.baseDir, lm.currentUUID, utils.MetaFilename) - err = ioutil2.WriteFileAtomic(filename, buf.Bytes(), 0644) + err = ioutil2.WriteFileAtomic(filename, buf.Bytes(), 0o644) if err != nil { return terror.ErrRelayFlushLocalMeta.Delegate(err) } @@ -252,7 +250,7 @@ func (lm *LocalMeta) doFlush() error { return nil } -// Dirty implements Meta.Dirty +// Dirty implements Meta.Dirty. func (lm *LocalMeta) Dirty() bool { lm.RLock() defer lm.RUnlock() @@ -260,7 +258,7 @@ func (lm *LocalMeta) Dirty() bool { return lm.dirty } -// Dir implements Meta.Dir +// Dir implements Meta.Dir. func (lm *LocalMeta) Dir() string { lm.RLock() defer lm.RUnlock() @@ -268,7 +266,7 @@ func (lm *LocalMeta) Dir() string { return filepath.Join(lm.baseDir, lm.currentUUID) } -// AddDir implements Meta.AddDir +// AddDir implements Meta.AddDir. func (lm *LocalMeta) AddDir(serverUUID string, newPos *mysql.Position, newGTID gtid.Set, uuidSuffix int) error { lm.Lock() defer lm.Unlock() @@ -300,7 +298,7 @@ func (lm *LocalMeta) AddDir(serverUUID string, newPos *mysql.Position, newGTID g } // make sub dir for UUID - err := os.Mkdir(filepath.Join(lm.baseDir, newUUID), 0744) + err := os.Mkdir(filepath.Join(lm.baseDir, newUUID), 0o744) if err != nil { return terror.ErrRelayMkdir.Delegate(err) } @@ -335,7 +333,7 @@ func (lm *LocalMeta) AddDir(serverUUID string, newPos *mysql.Position, newGTID g return lm.doFlush() } -// Pos implements Meta.Pos +// Pos implements Meta.Pos. func (lm *LocalMeta) Pos() (string, mysql.Position) { lm.RLock() defer lm.RUnlock() @@ -343,7 +341,7 @@ func (lm *LocalMeta) Pos() (string, mysql.Position) { return lm.currentUUID, mysql.Position{Name: lm.BinLogName, Pos: lm.BinLogPos} } -// GTID implements Meta.GTID +// GTID implements Meta.GTID. func (lm *LocalMeta) GTID() (string, gtid.Set) { lm.RLock() defer lm.RUnlock() @@ -354,14 +352,14 @@ func (lm *LocalMeta) GTID() (string, gtid.Set) { return lm.currentUUID, nil } -// UUID implements Meta.UUID +// UUID implements Meta.UUID. func (lm *LocalMeta) UUID() string { lm.RLock() defer lm.RUnlock() return lm.currentUUID } -// TrimUUIDs implements Meta.TrimUUIDs +// TrimUUIDs implements Meta.TrimUUIDs. func (lm *LocalMeta) TrimUUIDs() ([]string, error) { lm.Lock() defer lm.Unlock() @@ -392,14 +390,14 @@ func (lm *LocalMeta) TrimUUIDs() ([]string, error) { return trimmed, nil } -// String implements Meta.String +// String implements Meta.String. func (lm *LocalMeta) String() string { uuid, pos := lm.Pos() _, gs := lm.GTID() return fmt.Sprintf("master-uuid = %s, relay-binlog = %v, relay-binlog-gtid = %v", uuid, pos, gs) } -// updateIndexFile updates the content of server-uuid.index file +// updateIndexFile updates the content of server-uuid.index file. func (lm *LocalMeta) updateIndexFile(uuids []string) error { var buf bytes.Buffer for _, uuid := range uuids { @@ -407,7 +405,7 @@ func (lm *LocalMeta) updateIndexFile(uuids []string) error { buf.WriteString("\n") } - err := ioutil2.WriteFileAtomic(lm.uuidIndexPath, buf.Bytes(), 0644) + err := ioutil2.WriteFileAtomic(lm.uuidIndexPath, buf.Bytes(), 0o644) return terror.ErrRelayUpdateIndexFile.Delegate(err, lm.uuidIndexPath) } @@ -429,7 +427,7 @@ func (lm *LocalMeta) verifyUUIDs(uuids []string) error { return nil } -// updateCurrentUUID updates current UUID +// updateCurrentUUID updates current UUID. func (lm *LocalMeta) updateCurrentUUID(uuid string) error { _, suffix, err := utils.ParseSuffixForUUID(uuid) if err != nil { @@ -450,7 +448,7 @@ func (lm *LocalMeta) updateCurrentUUID(uuid string) error { return nil } -// loadMetaData loads meta information from meta data file +// loadMetaData loads meta information from meta data file. func (lm *LocalMeta) loadMetaData() error { lm.gset = lm.emptyGSet.Clone() diff --git a/relay/meta_test.go b/relay/meta_test.go index 213c4e9439..5b2a321ace 100644 --- a/relay/meta_test.go +++ b/relay/meta_test.go @@ -27,8 +27,7 @@ import ( var _ = Suite(&testMetaSuite{}) -type testMetaSuite struct { -} +type testMetaSuite struct{} type MetaTestCase struct { uuid string @@ -99,7 +98,7 @@ func (r *testMetaSuite) TestLocalMeta(c *C) { // set currentUUID because lm.doFlush need it currentUUID := "uuid.000001" - c.Assert(os.MkdirAll(path.Join(dir, currentUUID), 0777), IsNil) + c.Assert(os.MkdirAll(path.Join(dir, currentUUID), 0o777), IsNil) setLocalMetaWithCurrentUUID := func() { lm = NewLocalMeta("mysql", dir) lm.(*LocalMeta).currentUUID = currentUUID diff --git a/relay/metrics.go b/relay/metrics.go index 5a3a122dd3..85141c2595 100644 --- a/relay/metrics.go +++ b/relay/metrics.go @@ -43,7 +43,7 @@ var ( }, []string{"node"}) // split sub directory info from relayLogPosGauge / relayLogFileGauge - // to make compare relayLogFileGauge for master / relay more easier + // to make compare relayLogFileGauge for master / relay more easier. relaySubDirIndex = metricsproxy.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "dm", @@ -52,7 +52,7 @@ var ( Help: "current relay sub directory index", }, []string{"node", "uuid"}) - // should alert if available space < 10G + // should alert if available space < 10G. relayLogSpaceGauge = metricsproxy.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "dm", @@ -61,7 +61,7 @@ var ( Help: "the space of storage for relay component", }, []string{"type"}) // type can be 'capacity' and 'available'. - // should alert + // should alert. relayLogDataCorruptionCounter = prometheus.NewCounter( prometheus.CounterOpts{ Namespace: "dm", @@ -88,7 +88,7 @@ var ( Buckets: prometheus.ExponentialBuckets(0.000005, 2, 25), }) - // should alert + // should alert. relayLogWriteErrorCounter = prometheus.NewCounter( prometheus.CounterOpts{ Namespace: "dm", @@ -97,7 +97,7 @@ var ( Help: "write relay log error count", }) - // should alert + // should alert. binlogReadErrorCounter = prometheus.NewCounter( prometheus.CounterOpts{ Namespace: "dm", @@ -124,7 +124,7 @@ var ( Buckets: prometheus.ExponentialBuckets(0.000005, 2, 25), }) - // should alert + // should alert. relayExitWithErrorCounter = prometheus.NewCounter( prometheus.CounterOpts{ Namespace: "dm", diff --git a/relay/purger/file.go b/relay/purger/file.go index e48e39a468..94922d1aa7 100644 --- a/relay/purger/file.go +++ b/relay/purger/file.go @@ -26,14 +26,14 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// subRelayFiles represents relay log files in one sub directory +// subRelayFiles represents relay log files in one sub directory. type subRelayFiles struct { dir string // sub directory path files []string // path of relay log files hasAll bool // whether all relay log files in @dir are included in @files } -// purgeRelayFilesBeforeFile purge relay log files which are older than safeRelay +// purgeRelayFilesBeforeFile purge relay log files which are older than safeRelay. func purgeRelayFilesBeforeFile(logger log.Logger, relayBaseDir string, uuids []string, safeRelay *streamer.RelayLogInfo) error { files, err := getRelayFilesBeforeFile(logger, relayBaseDir, uuids, safeRelay) if err != nil { @@ -43,7 +43,7 @@ func purgeRelayFilesBeforeFile(logger log.Logger, relayBaseDir string, uuids []s return purgeRelayFiles(logger, files) } -// purgeRelayFilesBeforeFileAndTime purge relay log files which are older than safeRelay and safeTime +// purgeRelayFilesBeforeFileAndTime purge relay log files which are older than safeRelay and safeTime. func purgeRelayFilesBeforeFileAndTime(logger log.Logger, relayBaseDir string, uuids []string, safeRelay *streamer.RelayLogInfo, safeTime time.Time) error { files, err := getRelayFilesBeforeFileAndTime(logger, relayBaseDir, uuids, safeRelay, safeTime) if err != nil { @@ -53,7 +53,7 @@ func purgeRelayFilesBeforeFileAndTime(logger log.Logger, relayBaseDir string, uu return purgeRelayFiles(logger, files) } -// getRelayFilesBeforeFile gets a list of relay log files which are older than safeRelay +// getRelayFilesBeforeFile gets a list of relay log files which are older than safeRelay. func getRelayFilesBeforeFile(logger log.Logger, relayBaseDir string, uuids []string, safeRelay *streamer.RelayLogInfo) ([]*subRelayFiles, error) { // discard all newer UUIDs uuids, err := trimUUIDs(uuids, safeRelay) @@ -66,7 +66,7 @@ func getRelayFilesBeforeFile(logger log.Logger, relayBaseDir string, uuids []str return files, err } -// getRelayFilesBeforeTime gets a list of relay log files which have modified time earlier than safeTime +// getRelayFilesBeforeTime gets a list of relay log files which have modified time earlier than safeTime. func getRelayFilesBeforeFileAndTime(logger log.Logger, relayBaseDir string, uuids []string, safeRelay *streamer.RelayLogInfo, safeTime time.Time) ([]*subRelayFiles, error) { // discard all newer UUIDs uuids, err := trimUUIDs(uuids, safeRelay) @@ -77,9 +77,9 @@ func getRelayFilesBeforeFileAndTime(logger log.Logger, relayBaseDir string, uuid return collectRelayFilesBeforeFileAndTime(logger, relayBaseDir, uuids, safeRelay.Filename, safeTime) } -// trimUUIDs trims all newer UUIDs than safeRelay +// trimUUIDs trims all newer UUIDs than safeRelay. func trimUUIDs(uuids []string, safeRelay *streamer.RelayLogInfo) ([]string, error) { - var endIdx = -1 + endIdx := -1 for i, uuid := range uuids { if uuid == safeRelay.UUID { endIdx = i @@ -93,7 +93,7 @@ func trimUUIDs(uuids []string, safeRelay *streamer.RelayLogInfo) ([]string, erro return uuids[:endIdx+1], nil } -// collectRelayFilesBeforeFileAndTime collects relay log files before safeFilename (and before safeTime) +// collectRelayFilesBeforeFileAndTime collects relay log files before safeFilename (and before safeTime). func collectRelayFilesBeforeFileAndTime(logger log.Logger, relayBaseDir string, uuids []string, safeFilename string, safeTime time.Time) ([]*subRelayFiles, error) { // NOTE: test performance when removing a large number of relay log files and decide whether need to limit files removed every time files := make([]*subRelayFiles, 0, 1) @@ -158,7 +158,7 @@ func collectRelayFilesBeforeFileAndTime(logger log.Logger, relayBaseDir string, return files, nil } -// purgeRelayFiles purges relay log files and directories if them become empty +// purgeRelayFiles purges relay log files and directories if them become empty. func purgeRelayFiles(logger log.Logger, files []*subRelayFiles) error { startTime := time.Now() defer func() { diff --git a/relay/purger/file_test.go b/relay/purger/file_test.go index 03b3c0fd70..c7f02d8f98 100644 --- a/relay/purger/file_test.go +++ b/relay/purger/file_test.go @@ -106,7 +106,7 @@ func (t *testPurgerSuite) TestPurgeRelayFilesBeforeFile(c *C) { // write a fake meta file to first sub dir fakeMeta := filepath.Join(relayDirsPath[0], utils.MetaFilename) - c.Assert(ioutil.WriteFile(fakeMeta, []byte{}, 0666), IsNil) + c.Assert(ioutil.WriteFile(fakeMeta, []byte{}, 0o666), IsNil) // purge all relay log files in first and second sub dir, and some in third sub dir err = purgeRelayFilesBeforeFile(log.L(), baseDir, t.uuids, safeRelay) @@ -165,7 +165,7 @@ func (t *testPurgerSuite) TestPurgeRelayFilesBeforeFileAndTime(c *C) { // write a fake meta file to first sub dir fakeMeta := filepath.Join(relayDirsPath[0], utils.MetaFilename) - c.Assert(ioutil.WriteFile(fakeMeta, []byte{}, 0666), IsNil) + c.Assert(ioutil.WriteFile(fakeMeta, []byte{}, 0o666), IsNil) // purge all relay log files in first and second sub dir, and some in third sub dir err = purgeRelayFilesBeforeFileAndTime(log.L(), baseDir, t.uuids, safeRelay, safeTime) diff --git a/relay/purger/purger.go b/relay/purger/purger.go index e3f9fa4596..87a39c0064 100644 --- a/relay/purger/purger.go +++ b/relay/purger/purger.go @@ -30,13 +30,13 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// RelayOperator represents an operator for relay log files, like writer, reader +// RelayOperator represents an operator for relay log files, like writer, reader. type RelayOperator interface { // EarliestActiveRelayLog returns the earliest active relay log info in this operator EarliestActiveRelayLog() *streamer.RelayLogInfo } -// PurgeInterceptor represents an interceptor may forbid the purge process +// PurgeInterceptor represents an interceptor may forbid the purge process. type PurgeInterceptor interface { // ForbidPurge returns whether forbidding purge currently and an optional message ForbidPurge() (bool, string) @@ -48,7 +48,7 @@ const ( stageClosed ) -// Purger purges relay log according to some strategies +// Purger purges relay log according to some strategies. type Purger interface { // Start starts strategies by config Start() @@ -60,10 +60,10 @@ type Purger interface { Do(ctx context.Context, req *pb.PurgeRelayRequest) error } -// NewPurger creates a new purger +// NewPurger creates a new purger. var NewPurger = NewRelayPurger -// RelayPurger purges relay log according to some strategies +// RelayPurger purges relay log according to some strategies. type RelayPurger struct { lock sync.RWMutex wg sync.WaitGroup @@ -81,7 +81,7 @@ type RelayPurger struct { logger log.Logger } -// NewRelayPurger creates a new purger +// NewRelayPurger creates a new purger. func NewRelayPurger(cfg config.PurgeConfig, baseRelayDir string, operators []RelayOperator, interceptors []PurgeInterceptor) Purger { p := &RelayPurger{ cfg: cfg, @@ -102,7 +102,7 @@ func NewRelayPurger(cfg config.PurgeConfig, baseRelayDir string, operators []Rel return p } -// Start starts strategies by config +// Start starts strategies by config. func (p *RelayPurger) Start() { if !p.running.CompareAndSwap(stageNew, stageRunning) { return @@ -123,7 +123,7 @@ func (p *RelayPurger) Start() { } // run starts running the process -// NOTE: ensure run is called at most once of a Purger +// NOTE: ensure run is called at most once of a Purger. func (p *RelayPurger) run() { ticker := time.NewTicker(time.Duration(p.cfg.Interval) * time.Second) defer ticker.Stop() @@ -142,7 +142,7 @@ func (p *RelayPurger) run() { } } -// Close stops the started strategies +// Close stops the started strategies. func (p *RelayPurger) Close() { if !p.running.CompareAndSwap(stageRunning, stageClosed) { return @@ -158,26 +158,27 @@ func (p *RelayPurger) Close() { p.wg.Wait() } -// Purging returns whether the purger is purging +// Purging returns whether the purger is purging. func (p *RelayPurger) Purging() bool { return p.purgingStrategy.Get() != uint32(strategyNone) } -// Do does the purge process one time +// Do does the purge process one time. func (p *RelayPurger) Do(ctx context.Context, req *pb.PurgeRelayRequest) error { uuids, err := utils.ParseUUIDIndex(p.indexPath) if err != nil { return terror.Annotatef(err, "parse UUID index file %s", p.indexPath) } - if req.Inactive { + switch { + case req.Inactive: ps := p.strategies[strategyInactive] args := &inactiveArgs{ relayBaseDir: p.baseRelayDir, uuids: uuids, } return p.doPurge(ps, args) - } else if req.Time > 0 { + case req.Time > 0: ps := p.strategies[strategyTime] args := &timeArgs{ relayBaseDir: p.baseRelayDir, @@ -185,7 +186,7 @@ func (p *RelayPurger) Do(ctx context.Context, req *pb.PurgeRelayRequest) error { uuids: uuids, } return p.doPurge(ps, args) - } else if len(req.Filename) > 0 { + case len(req.Filename) > 0: ps := p.strategies[strategyFilename] args := &filenameArgs{ relayBaseDir: p.baseRelayDir, @@ -194,11 +195,12 @@ func (p *RelayPurger) Do(ctx context.Context, req *pb.PurgeRelayRequest) error { uuids: uuids, } return p.doPurge(ps, args) + default: + return terror.ErrRelayPurgeRequestNotValid.Generate(req) } - return terror.ErrRelayPurgeRequestNotValid.Generate(req) } -// tryPurge tries to do purge by check condition first +// tryPurge tries to do purge by check condition first. func (p *RelayPurger) tryPurge() { strategy, args, err := p.check() if err != nil { @@ -214,7 +216,7 @@ func (p *RelayPurger) tryPurge() { } } -// doPurge does the purging operation +// doPurge does the purging operation. func (p *RelayPurger) doPurge(ps PurgeStrategy, args StrategyArgs) error { if !p.purgingStrategy.CompareAndSwap(uint32(strategyNone), uint32(ps.Type())) { return terror.ErrRelayOtherStrategyIsPurging.Generate(ps.Type()) @@ -289,7 +291,7 @@ func (p *RelayPurger) check() (PurgeStrategy, StrategyArgs, error) { return nil, nil, nil } -// earliestActiveRelayLog returns the current earliest active relay log info +// earliestActiveRelayLog returns the current earliest active relay log info. func (p *RelayPurger) earliestActiveRelayLog() *streamer.RelayLogInfo { var earliest *streamer.RelayLogInfo for _, op := range p.operators { @@ -303,26 +305,26 @@ func (p *RelayPurger) earliestActiveRelayLog() *streamer.RelayLogInfo { return earliest } -/************ dummy purger **************/ +/************ dummy purger *************.*/ type dummyPurger struct{} -// NewDummyPurger returns a dummy purger +// NewDummyPurger returns a dummy purger. func NewDummyPurger(cfg config.PurgeConfig, baseRelayDir string, operators []RelayOperator, interceptors []PurgeInterceptor) Purger { return &dummyPurger{} } -// Start implements interface of Purger +// Start implements interface of Purger. func (d *dummyPurger) Start() {} -// Close implements interface of Purger +// Close implements interface of Purger. func (d *dummyPurger) Close() {} -// Purging implements interface of Purger +// Purging implements interface of Purger. func (d *dummyPurger) Purging() bool { return false } -// Do implements interface of Purger +// Do implements interface of Purger. func (d *dummyPurger) Do(ctx context.Context, req *pb.PurgeRelayRequest) error { return nil } diff --git a/relay/purger/purger_test.go b/relay/purger/purger_test.go index edb84d389b..3ff4630a18 100644 --- a/relay/purger/purger_test.go +++ b/relay/purger/purger_test.go @@ -207,8 +207,8 @@ func (t *testPurgerSuite) TestPurgeAutomaticallyTime(c *C) { } // change files' modification time - aTime := time.Now().Add(time.Duration(-cfg.Expires) * 3 * time.Hour) - mTime := time.Now().Add(time.Duration(-cfg.Expires) * 2 * time.Hour) + aTime := time.Now().Add(time.Duration(-cfg.Expires*3) * time.Hour) + mTime := time.Now().Add(time.Duration(-cfg.Expires*2) * time.Hour) for _, fps := range relayFilesPath { for _, fp := range fps { err = os.Chtimes(fp, aTime, mTime) @@ -282,7 +282,7 @@ func (t *testPurgerSuite) genRelayLogFiles(c *C, baseDir string, safeTimeIdxI, s for _, uuid := range t.uuids { dir := filepath.Join(baseDir, uuid) - err := os.Mkdir(dir, 0700) + err := os.Mkdir(dir, 0o700) c.Assert(err, IsNil) relayDirsPath = append(relayDirsPath, dir) } @@ -293,7 +293,7 @@ func (t *testPurgerSuite) genRelayLogFiles(c *C, baseDir string, safeTimeIdxI, s relayFilesPath = append(relayFilesPath, []string{}) for j, fn := range t.relayFiles[i] { fp := filepath.Join(dir, fn) - err2 := ioutil.WriteFile(fp, []byte("meaningless file content"), 0644) + err2 := ioutil.WriteFile(fp, []byte("meaningless file content"), 0o644) c.Assert(err2, IsNil) relayFilesPath[i] = append(relayFilesPath[i], fp) @@ -317,7 +317,7 @@ func (t *testPurgerSuite) genUUIDIndexFile(baseDir string) error { buf.WriteString("\n") } - return ioutil2.WriteFileAtomic(fp, buf.Bytes(), 0644) + return ioutil2.WriteFileAtomic(fp, buf.Bytes(), 0o644) } type fakeInterceptor struct { diff --git a/relay/purger/strategy.go b/relay/purger/strategy.go index 41f55237e9..4b49328d5e 100644 --- a/relay/purger/strategy.go +++ b/relay/purger/strategy.go @@ -44,7 +44,7 @@ func (s strategyType) String() string { // two purge behaviors // 1. purge in the background // 2. do one time purge process -// a strategy can support both or one of them +// a strategy can support both or one of them. type PurgeStrategy interface { // Check checks whether need to do the purge in the background automatically Check(args interface{}) (bool, error) @@ -59,7 +59,7 @@ type PurgeStrategy interface { Type() strategyType } -// StrategyArgs represents args needed by purge strategy +// StrategyArgs represents args needed by purge strategy. type StrategyArgs interface { // SetActiveRelayLog sets active relay log info in args // this should be called before do the purging diff --git a/relay/purger/strategy_filename.go b/relay/purger/strategy_filename.go index e3148b718a..b7a6705a9b 100644 --- a/relay/purger/strategy_filename.go +++ b/relay/purger/strategy_filename.go @@ -26,12 +26,10 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -var ( - fakeTaskName = strategyFilename.String() -) +var fakeTaskName = strategyFilename.String() // filenameArgs represents args needed by filenameStrategy -// NOTE: should handle master-slave switch +// NOTE: should handle master-slave switch. type filenameArgs struct { relayBaseDir string filename string // specified end safe filename @@ -79,7 +77,7 @@ func (fa *filenameArgs) String() string { } // filenameStrategy represents a relay purge strategy by filename -// similar to `PURGE BINARY LOGS TO` +// similar to `PURGE BINARY LOGS TO`. type filenameStrategy struct { purging sync2.AtomicInt32 diff --git a/relay/purger/strategy_inactive.go b/relay/purger/strategy_inactive.go index 9e402697c4..f8942cfe4f 100644 --- a/relay/purger/strategy_inactive.go +++ b/relay/purger/strategy_inactive.go @@ -25,7 +25,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// inactiveArgs represents args needed by inactiveStrategy +// inactiveArgs represents args needed by inactiveStrategy. type inactiveArgs struct { relayBaseDir string uuids []string diff --git a/relay/purger/strategy_space.go b/relay/purger/strategy_space.go index 3d065adfed..4401c8d073 100644 --- a/relay/purger/strategy_space.go +++ b/relay/purger/strategy_space.go @@ -26,7 +26,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// spaceArgs represents args needed by spaceStrategy +// spaceArgs represents args needed by spaceStrategy. type spaceArgs struct { relayBaseDir string remainSpace int64 // if remain space (GB) in @RelayBaseDir less than this, then it can be purged @@ -43,7 +43,7 @@ func (sa *spaceArgs) String() string { sa.relayBaseDir, sa.remainSpace, strings.Join(sa.uuids, ";"), sa.activeRelayLog) } -// spaceStrategy represents a relay purge strategy by remain space in dm-worker node +// spaceStrategy represents a relay purge strategy by remain space in dm-worker node. type spaceStrategy struct { purging sync2.AtomicInt32 diff --git a/relay/purger/strategy_time.go b/relay/purger/strategy_time.go index 337eda6a0a..ce8faf9a53 100644 --- a/relay/purger/strategy_time.go +++ b/relay/purger/strategy_time.go @@ -26,7 +26,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// timeArgs represents args needed by timeStrategy +// timeArgs represents args needed by timeStrategy. type timeArgs struct { relayBaseDir string safeTime time.Time // if file's modified time is older than this, then it can be purged @@ -44,7 +44,7 @@ func (ta *timeArgs) String() string { } // timeStrategy represents a relay purge strategy by time -// similar to `PURGE BINARY LOGS BEFORE` in MySQL +// similar to `PURGE BINARY LOGS BEFORE` in MySQL. type timeStrategy struct { purging sync2.AtomicInt32 diff --git a/relay/reader/error.go b/relay/reader/error.go index db00892d18..0587a30a96 100644 --- a/relay/reader/error.go +++ b/relay/reader/error.go @@ -21,9 +21,7 @@ import ( // isRetryableError checks whether the error is retryable. func isRetryableError(err error) bool { - err = errors.Cause(err) - switch err { - case context.DeadlineExceeded: + if err = errors.Cause(err); err == context.DeadlineExceeded { return true } return false diff --git a/relay/reader/error_test.go b/relay/reader/error_test.go index f7eef0e287..38200a22bf 100644 --- a/relay/reader/error_test.go +++ b/relay/reader/error_test.go @@ -20,12 +20,9 @@ import ( "github.com/pingcap/errors" ) -var ( - _ = check.Suite(&testErrorSuite{}) -) +var _ = check.Suite(&testErrorSuite{}) -type testErrorSuite struct { -} +type testErrorSuite struct{} func (t *testErrorSuite) TestRetryable(c *check.C) { err := errors.New("custom error") diff --git a/relay/reader/reader_test.go b/relay/reader/reader_test.go index 9502786d0f..aabdaf3650 100644 --- a/relay/reader/reader_test.go +++ b/relay/reader/reader_test.go @@ -25,16 +25,13 @@ import ( br "github.com/pingcap/dm/pkg/binlog/reader" ) -var ( - _ = check.Suite(&testReaderSuite{}) -) +var _ = check.Suite(&testReaderSuite{}) func TestSuite(t *testing.T) { check.TestingT(t) } -type testReaderSuite struct { -} +type testReaderSuite struct{} func (t *testReaderSuite) TestInterface(c *check.C) { cases := []*replication.BinlogEvent{ diff --git a/relay/relay.go b/relay/relay.go old mode 100755 new mode 100644 index 4b9ac919fb..ef73a7c29a --- a/relay/relay.go +++ b/relay/relay.go @@ -51,10 +51,8 @@ import ( "github.com/pingcap/dm/relay/writer" ) -var ( - // used to fill RelayLogInfo - fakeTaskName = "relay" -) +// used to fill RelayLogInfo. +var fakeTaskName = "relay" const ( flushMetaInterval = 30 * time.Second @@ -71,7 +69,7 @@ var NewRelay = NewRealRelay var _ Process = &Relay{} -// Process defines mysql-like relay log process unit +// Process defines mysql-like relay log process unit. type Process interface { // Init initial relat log unit Init(ctx context.Context) (err error) @@ -152,7 +150,7 @@ func (r *Relay) Init(ctx context.Context) (err error) { r.db = db rollbackHolder.Add(fr.FuncRollback{Name: "close-DB", Fn: r.closeDB}) - if err2 := os.MkdirAll(r.cfg.RelayDir, 0755); err2 != nil { + if err2 := os.MkdirAll(r.cfg.RelayDir, 0o755); err2 != nil { return terror.ErrRelayMkdir.Delegate(err2) } @@ -324,7 +322,7 @@ func (r *Relay) process(ctx context.Context) error { } } -// PurgeRelayDir implements the dm.Unit interface +// PurgeRelayDir implements the dm.Unit interface. func (r *Relay) PurgeRelayDir() error { dir := r.cfg.RelayDir d, err := os.Open(dir) @@ -471,7 +469,7 @@ func (r *Relay) handleEvents(ctx context.Context, reader2 reader.Reader, transfo binlogReadDurationHistogram.Observe(time.Since(readTimer).Seconds()) failpoint.Inject("BlackholeReadBinlog", func(_ failpoint.Value) { - //r.logger.Info("back hole read binlog takes effects") + // r.logger.Info("back hole read binlog takes effects") failpoint.Continue() }) @@ -773,8 +771,7 @@ func (r *Relay) setUpWriter(parser2 *parser.Parser) (writer.Writer, error) { Filename: pos.Name, } writer2 := writer.NewFileWriter(r.logger, cfg, parser2) - err := writer2.Start() - if err != nil { + if err := writer2.Start(); err != nil { return nil, terror.Annotatef(err, "start writer for UUID %s with config %+v", uuid, cfg) } @@ -791,22 +788,22 @@ func (r *Relay) IsClosed() bool { return r.closed.Get() } -// SaveMeta save relay meta and update meta in RelayLogInfo +// SaveMeta save relay meta and update meta in RelayLogInfo. func (r *Relay) SaveMeta(pos mysql.Position, gset gtid.Set) error { return r.meta.Save(pos, gset) } -// ResetMeta reset relay meta +// ResetMeta reset relay meta. func (r *Relay) ResetMeta() { r.meta = NewLocalMeta(r.cfg.Flavor, r.cfg.RelayDir) } -// FlushMeta flush relay meta +// FlushMeta flush relay meta. func (r *Relay) FlushMeta() error { return r.meta.Flush() } -// stopSync stops syncing, now it used by Close and Pause +// stopSync stops syncing, now it used by Close and Pause. func (r *Relay) stopSync() { if err := r.FlushMeta(); err != nil { r.logger.Error("flush checkpoint", zap.Error(err)) @@ -877,12 +874,12 @@ func (r *Relay) Type() pb.UnitType { return pb.UnitType_Relay } -// IsFreshTask implements Unit.IsFreshTask +// IsFreshTask implements Unit.IsFreshTask. func (r *Relay) IsFreshTask() (bool, error) { return true, nil } -// Pause pauses the process, it can be resumed later +// Pause pauses the process, it can be resumed later. func (r *Relay) Pause() { if r.IsClosed() { r.logger.Warn("try to pause, but already closed") @@ -892,18 +889,18 @@ func (r *Relay) Pause() { r.stopSync() } -// Resume resumes the paused process +// Resume resumes the paused process. func (r *Relay) Resume(ctx context.Context, pr chan pb.ProcessResult) { // do nothing now, re-process called `Process` from outer directly } -// Update implements Unit.Update +// Update implements Unit.Update. func (r *Relay) Update(cfg *config.SubTaskConfig) error { // not support update configuration now return nil } -// Reload updates config +// Reload updates config. func (r *Relay) Reload(newCfg *Config) error { r.Lock() defer r.Unlock() @@ -938,7 +935,7 @@ func (r *Relay) Reload(newCfg *Config) error { return nil } -// setActiveRelayLog sets or updates the current active relay log to file +// setActiveRelayLog sets or updates the current active relay log to file. func (r *Relay) setActiveRelayLog(filename string) { uuid := r.meta.UUID() _, suffix, _ := utils.ParseSuffixForUUID(uuid) @@ -953,7 +950,7 @@ func (r *Relay) setActiveRelayLog(filename string) { r.activeRelayLog.Unlock() } -// ActiveRelayLog returns the current active RelayLogInfo +// ActiveRelayLog returns the current active RelayLogInfo. func (r *Relay) ActiveRelayLog() *pkgstreamer.RelayLogInfo { r.activeRelayLog.RLock() defer r.activeRelayLog.RUnlock() diff --git a/relay/relay_test.go b/relay/relay_test.go index eaeca7cb06..09b9e2f3dc 100644 --- a/relay/relay_test.go +++ b/relay/relay_test.go @@ -30,7 +30,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/parser" - "github.com/siddontang/go-mysql/mysql" gmysql "github.com/siddontang/go-mysql/mysql" "github.com/siddontang/go-mysql/replication" @@ -54,8 +53,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testRelaySuite struct { -} +type testRelaySuite struct{} func (t *testRelaySuite) SetUpSuite(c *C) { c.Assert(log.InitLogger(&log.Config{}), IsNil) @@ -176,7 +174,7 @@ func (t *testRelaySuite) TestTryRecoverLatestFile(c *C) { startPos = gmysql.Position{Name: filename, Pos: 123} parser2 = parser.New() - relayCfg = newRelayCfg(c, mysql.MySQLFlavor) + relayCfg = newRelayCfg(c, gmysql.MySQLFlavor) r = NewRelay(relayCfg).(*Relay) ) c.Assert(failpoint.Enable("github.com/pingcap/dm/pkg/utils/GetGTIDPurged", `return("406a3f61-690d-11e7-87c5-6c92bf46f384:1-122")`), IsNil) @@ -213,7 +211,7 @@ func (t *testRelaySuite) TestTryRecoverLatestFile(c *C) { g, events, data := genBinlogEventsWithGTIDs(c, relayCfg.Flavor, previousGTIDSet, latestGTID1, latestGTID2) // write events into relay log file - err = ioutil.WriteFile(filepath.Join(r.meta.Dir(), filename), data, 0600) + err = ioutil.WriteFile(filepath.Join(r.meta.Dir(), filename), data, 0o600) c.Assert(err, IsNil) // all events/transactions are complete, no need to recover @@ -225,7 +223,7 @@ func (t *testRelaySuite) TestTryRecoverLatestFile(c *C) { t.verifyMetadata(c, r, uuidWithSuffix, pos, recoverGTIDSetStr, []string{uuidWithSuffix}) // write some invalid data into the relay log file - f, err = os.OpenFile(filepath.Join(r.meta.Dir(), filename), os.O_WRONLY|os.O_APPEND, 0600) + f, err = os.OpenFile(filepath.Join(r.meta.Dir(), filename), os.O_WRONLY|os.O_APPEND, 0o600) c.Assert(err, IsNil) _, err = f.Write([]byte("invalid event data")) c.Assert(err, IsNil) @@ -266,7 +264,7 @@ func (t *testRelaySuite) TestTryRecoverMeta(c *C) { startPos = gmysql.Position{Name: filename, Pos: 123} parser2 = parser.New() - relayCfg = newRelayCfg(c, mysql.MySQLFlavor) + relayCfg = newRelayCfg(c, gmysql.MySQLFlavor) r = NewRelay(relayCfg).(*Relay) ) c.Assert(r.Init(context.Background()), IsNil) @@ -286,10 +284,10 @@ func (t *testRelaySuite) TestTryRecoverMeta(c *C) { g, _, data := genBinlogEventsWithGTIDs(c, relayCfg.Flavor, previousGTIDSet, latestGTID1, latestGTID2) // write events into relay log file - err = ioutil.WriteFile(filepath.Join(r.meta.Dir(), filename), data, 0600) + err = ioutil.WriteFile(filepath.Join(r.meta.Dir(), filename), data, 0o600) c.Assert(err, IsNil) // write some invalid data into the relay log file to trigger a recover. - f, err := os.OpenFile(filepath.Join(r.meta.Dir(), filename), os.O_WRONLY|os.O_APPEND, 0600) + f, err := os.OpenFile(filepath.Join(r.meta.Dir(), filename), os.O_WRONLY|os.O_APPEND, 0o600) c.Assert(err, IsNil) _, err = f.Write([]byte("invalid event data")) c.Assert(err, IsNil) @@ -303,7 +301,7 @@ func (t *testRelaySuite) TestTryRecoverMeta(c *C) { c.Assert(latestGTIDs.Equal(recoverGTIDSet), IsTrue) // write some invalid data into the relay log file again. - f, err = os.OpenFile(filepath.Join(r.meta.Dir(), filename), os.O_WRONLY|os.O_APPEND, 0600) + f, err = os.OpenFile(filepath.Join(r.meta.Dir(), filename), os.O_WRONLY|os.O_APPEND, 0o600) c.Assert(err, IsNil) _, err = f.Write([]byte("invalid event data")) c.Assert(err, IsNil) @@ -389,7 +387,7 @@ func (t *testRelaySuite) TestHandleEvent(c *C) { reader2 = &mockReader{} transformer2 = transformer.NewTransformer(parser.New()) writer2 = &mockWriter{} - relayCfg = newRelayCfg(c, mysql.MariaDBFlavor) + relayCfg = newRelayCfg(c, gmysql.MariaDBFlavor) r = NewRelay(relayCfg).(*Relay) eventHeader = &replication.EventHeader{ @@ -465,7 +463,8 @@ func (t *testRelaySuite) TestHandleEvent(c *C) { reader2.err = nil reader2.result.Event = &replication.BinlogEvent{ Header: &replication.EventHeader{EventType: replication.HEARTBEAT_EVENT}, - Event: &replication.GenericEvent{}} + Event: &replication.GenericEvent{}, + } ctx4, cancel4 := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel4() err = r.handleEvents(ctx4, reader2, transformer2, writer2) @@ -495,7 +494,7 @@ func (t *testRelaySuite) TestReSetupMeta(c *C) { defer cancel() var ( - relayCfg = newRelayCfg(c, mysql.MySQLFlavor) + relayCfg = newRelayCfg(c, gmysql.MySQLFlavor) r = NewRelay(relayCfg).(*Relay) ) c.Assert(r.Init(context.Background()), IsNil) @@ -550,7 +549,7 @@ func (t *testRelaySuite) verifyMetadata(c *C, r *Relay, uuidExpected string, posExpected gmysql.Position, gsStrExpected string, uuidsExpected []string) { uuid, pos := r.meta.Pos() _, gs := r.meta.GTID() - gsExpected, err := gtid.ParserGTID(mysql.MySQLFlavor, gsStrExpected) + gsExpected, err := gtid.ParserGTID(gmysql.MySQLFlavor, gsStrExpected) c.Assert(err, IsNil) c.Assert(uuid, Equals, uuidExpected) c.Assert(pos, DeepEquals, posExpected) @@ -632,6 +631,7 @@ func (t *testRelaySuite) TestProcess(c *C) { // should got the last DDL gotLastDDL := false onEventFunc := func(e *replication.BinlogEvent) error { + // nolint:gocritic switch ev := e.Event.(type) { case *replication.QueryEvent: if bytes.Contains(ev.Query, []byte(lastDDL)) { diff --git a/relay/transformer/transformer.go b/relay/transformer/transformer.go index f164ce823f..d326739cc3 100644 --- a/relay/transformer/transformer.go +++ b/relay/transformer/transformer.go @@ -89,8 +89,7 @@ func (t *transformer) Transform(e *replication.BinlogEvent) Result { result.CanSaveGTID = true // need save GTID for XID case *replication.GenericEvent: // handle some un-parsed events - switch e.Header.EventType { - case replication.HEARTBEAT_EVENT: + if e.Header.EventType == replication.HEARTBEAT_EVENT { // ignore artificial heartbeat event // ref: https://dev.mysql.com/doc/internals/en/heartbeat-event.html result.Ignore = true diff --git a/relay/transformer/transformer_test.go b/relay/transformer/transformer_test.go index aec0da0b78..8bb110108a 100644 --- a/relay/transformer/transformer_test.go +++ b/relay/transformer/transformer_test.go @@ -26,16 +26,13 @@ import ( "github.com/pingcap/dm/pkg/gtid" ) -var ( - _ = check.Suite(&testTransformerSuite{}) -) +var _ = check.Suite(&testTransformerSuite{}) func TestSuite(t *testing.T) { check.TestingT(t) } -type testTransformerSuite struct { -} +type testTransformerSuite struct{} type Case struct { event *replication.BinlogEvent @@ -84,8 +81,7 @@ func (t *testTransformerSuite) TestTransform(c *check.C) { header.Timestamp = uint32(time.Now().Unix()) // set to non-zero // fake RotateEvent with zero logPos - fakeRotateHeader := replication.EventHeader{} - fakeRotateHeader = *header + fakeRotateHeader := *header ev, err = event.GenRotateEvent(&fakeRotateHeader, latestPos, []byte(nextLogName), position) c.Assert(err, check.IsNil) ev.Header.LogPos = 0 // set to zero @@ -146,8 +142,7 @@ func (t *testTransformerSuite) TestTransform(c *check.C) { }) // GenericEvent, HEARTBEAT_EVENT - genericHeader := replication.EventHeader{} - genericHeader = *header + genericHeader := *header ev = &replication.BinlogEvent{Header: &genericHeader, Event: &replication.GenericEvent{}} ev.Header.EventType = replication.HEARTBEAT_EVENT cases = append(cases, Case{ diff --git a/relay/util_test.go b/relay/util_test.go index cde2ab876a..cc824402d9 100644 --- a/relay/util_test.go +++ b/relay/util_test.go @@ -25,8 +25,7 @@ import ( var _ = Suite(&testUtilSuite{}) -type testUtilSuite struct { -} +type testUtilSuite struct{} func (t *testUtilSuite) TestIsNewServer(c *C) { ctx, cancel := context.WithTimeout(context.Background(), utils.DefaultDBTimeout) diff --git a/relay/writer/file.go b/relay/writer/file.go index 6d069922a0..8a6d89ce4c 100644 --- a/relay/writer/file.go +++ b/relay/writer/file.go @@ -236,7 +236,7 @@ func (w *FileWriter) handleRotateEvent(ev *replication.BinlogEvent) (result Resu return result, terror.ErrRelayWriterExpectRotateEv.Generate(ev.Header) } - var currFile = w.filename.Get() + currFile := w.filename.Get() defer func() { if err == nil { // update binlog filename if needed @@ -329,7 +329,7 @@ func (w *FileWriter) handlePotentialHoleOrDuplicate(ev *replication.BinlogEvent) // handleFileHoleExist tries to handle a potential hole after this event wrote. // A hole exists often because some binlog events not sent by the master. // If no hole exists, then ev may be a duplicate event. -// NOTE: handle cases when file size > 4GB +// NOTE: handle cases when file size > 4GB. func (w *FileWriter) handleFileHoleExist(ev *replication.BinlogEvent) (bool, error) { // 1. detect whether a hole exists evStartPos := int64(ev.Header.LogPos - ev.Header.EventSize) @@ -392,7 +392,7 @@ func (w *FileWriter) handleDuplicateEventsExist(ev *replication.BinlogEvent) (Re // b. update the GTID set with the event's GTID if the transaction finished // 3. truncate any incomplete events/transactions // now, we think a transaction finished if we received a XIDEvent or DDL in QueryEvent -// NOTE: handle cases when file size > 4GB +// NOTE: handle cases when file size > 4GB. func (w *FileWriter) doRecovering(ctx context.Context) (RecoverResult, error) { filename := filepath.Join(w.cfg.RelayDir, w.filename.Get()) fs, err := os.Stat(filename) @@ -420,7 +420,7 @@ func (w *FileWriter) doRecovering(ctx context.Context) (RecoverResult, error) { } // truncate the file - f, err := os.OpenFile(filename, os.O_WRONLY, 0644) + f, err := os.OpenFile(filename, os.O_WRONLY, 0o644) if err != nil { return RecoverResult{}, terror.Annotatef(terror.ErrRelayWriterFileOperate.New(err.Error()), "open %s", filename) } diff --git a/relay/writer/file_test.go b/relay/writer/file_test.go index e98599e96e..73e76d62eb 100644 --- a/relay/writer/file_test.go +++ b/relay/writer/file_test.go @@ -34,9 +34,7 @@ import ( "github.com/pingcap/dm/pkg/log" ) -var ( - _ = check.Suite(&testFileWriterSuite{}) -) +var _ = check.Suite(&testFileWriterSuite{}) func TestSuite(t *testing.T) { check.TestingT(t) @@ -209,7 +207,7 @@ func (t *testFileWriterSuite) TestFormatDescriptionEvent(c *check.C) { // check events by reading them back events := make([]*replication.BinlogEvent, 0, 2) - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { count++ if count > 2 { @@ -420,7 +418,8 @@ func (t *testFileWriterSuite) TestWriteMultiEvents(c *check.C) { ) insertRows[0] = []interface{}{int32(1)} events, data, err = g.GenDMLEvents(replication.WRITE_ROWS_EVENTv2, []*event.DMLData{ - {TableID: tableID, Schema: "db", Table: "tbl", ColumnType: columnType, Rows: insertRows}}) + {TableID: tableID, Schema: "db", Table: "tbl", ColumnType: columnType, Rows: insertRows}, + }) c.Assert(err, check.IsNil) allEvents = append(allEvents, events...) allData.Write(data) @@ -487,7 +486,7 @@ func (t *testFileWriterSuite) TestHandleFileHoleExist(c *check.C) { // read events back from the file to check the dummy event events := make([]*replication.BinlogEvent, 0, 3) - var count = 0 + count := 0 onEventFunc := func(e *replication.BinlogEvent) error { count++ if count > 3 { @@ -593,7 +592,7 @@ func (t *testFileWriterSuite) TestRecoverMySQL(c *check.C) { // write the events to a file filename := filepath.Join(cfg.RelayDir, cfg.Filename) - err = ioutil.WriteFile(filename, baseData, 0644) + err = ioutil.WriteFile(filename, baseData, 0o644) c.Assert(err, check.IsNil) // try recover, but in fact do nothing @@ -615,7 +614,7 @@ func (t *testFileWriterSuite) TestRecoverMySQL(c *check.C) { // write an incomplete event to the file corruptData := extraEvents[0].RawData[:len(extraEvents[0].RawData)-2] - f, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0644) + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0o644) c.Assert(err, check.IsNil) _, err = f.Write(corruptData) c.Assert(err, check.IsNil) @@ -639,7 +638,7 @@ func (t *testFileWriterSuite) TestRecoverMySQL(c *check.C) { c.Assert(fs.Size(), check.Equals, int64(len(baseData))) // write an incomplete transaction - f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0644) + f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0o644) c.Assert(err, check.IsNil) var extraLen int64 for i := 0; i < len(extraEvents)-1; i++ { @@ -667,7 +666,7 @@ func (t *testFileWriterSuite) TestRecoverMySQL(c *check.C) { c.Assert(fs.Size(), check.Equals, int64(len(baseData))) // write an completed transaction - f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0644) + f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0o644) c.Assert(err, check.IsNil) for i := 0; i < len(extraEvents); i++ { _, err = f.Write(extraEvents[i].RawData) @@ -702,11 +701,9 @@ func (t *testFileWriterSuite) TestRecoverMySQL(c *check.C) { } func (t *testFileWriterSuite) TestRecoverMySQLNone(c *check.C) { - var ( - cfg = &FileConfig{ - RelayDir: c.MkDir(), - } - ) + cfg := &FileConfig{ + RelayDir: c.MkDir(), + } w1 := NewFileWriter(log.L(), cfg, t.parser) defer w1.Close() diff --git a/relay/writer/file_util.go b/relay/writer/file_util.go index b46ed8396b..4e77c6449c 100644 --- a/relay/writer/file_util.go +++ b/relay/writer/file_util.go @@ -112,11 +112,12 @@ func checkFormatDescriptionEventExist(filename string) (bool, error) { // only parse single event eof, err := replication.NewBinlogParser().ParseSingleEvent(f, onEventFunc) - if found { + switch { + case found: return found, nil // if found is true, we return `true` even meet an error, because FormatDescriptionEvent exists. - } else if err != nil { + case err != nil: return false, terror.ErrRelayCheckFormatDescEventParseEv.Delegate(err, filename) - } else if eof { + case eof: return false, terror.ErrRelayCheckFormatDescEventParseEv.Delegate(io.EOF, filename) } return found, nil @@ -124,7 +125,7 @@ func checkFormatDescriptionEventExist(filename string) (bool, error) { // checkIsDuplicateEvent checks if the event is a duplicate event in the file. // It is not safe if there other routine is writing the file. -// NOTE: handle cases when file size > 4GB +// NOTE: handle cases when file size > 4GB. func checkIsDuplicateEvent(filename string, ev *replication.BinlogEvent) (bool, error) { // 1. check event start/end pos with the file size, and it's enough for most cases fs, err := os.Stat(filename) diff --git a/relay/writer/file_util_test.go b/relay/writer/file_util_test.go index 02262fafa7..ababb7db53 100644 --- a/relay/writer/file_util_test.go +++ b/relay/writer/file_util_test.go @@ -32,12 +32,9 @@ import ( "github.com/pingcap/dm/pkg/gtid" ) -var ( - _ = check.Suite(&testFileUtilSuite{}) -) +var _ = check.Suite(&testFileUtilSuite{}) -type testFileUtilSuite struct { -} +type testFileUtilSuite struct{} func (t *testFileUtilSuite) TestCheckBinlogHeaderExist(c *check.C) { // file not exists @@ -47,28 +44,28 @@ func (t *testFileUtilSuite) TestCheckBinlogHeaderExist(c *check.C) { c.Assert(exist, check.IsFalse) // empty file - err = ioutil.WriteFile(filename, nil, 0644) + err = ioutil.WriteFile(filename, nil, 0o644) c.Assert(err, check.IsNil) exist, err = checkBinlogHeaderExist(filename) c.Assert(err, check.IsNil) c.Assert(exist, check.IsFalse) // no enough data - err = ioutil.WriteFile(filename, replication.BinLogFileHeader[:len(replication.BinLogFileHeader)-1], 0644) + err = ioutil.WriteFile(filename, replication.BinLogFileHeader[:len(replication.BinLogFileHeader)-1], 0o644) c.Assert(err, check.IsNil) exist, err = checkBinlogHeaderExist(filename) c.Assert(err, check.ErrorMatches, ".*has no enough data.*") c.Assert(exist, check.IsFalse) // equal - err = ioutil.WriteFile(filename, replication.BinLogFileHeader, 0644) + err = ioutil.WriteFile(filename, replication.BinLogFileHeader, 0o644) c.Assert(err, check.IsNil) exist, err = checkBinlogHeaderExist(filename) c.Assert(err, check.IsNil) c.Assert(exist, check.IsTrue) // more data - err = ioutil.WriteFile(filename, bytes.Repeat(replication.BinLogFileHeader, 2), 0644) + err = ioutil.WriteFile(filename, bytes.Repeat(replication.BinLogFileHeader, 2), 0o644) c.Assert(err, check.IsNil) exist, err = checkBinlogHeaderExist(filename) c.Assert(err, check.IsNil) @@ -77,8 +74,8 @@ func (t *testFileUtilSuite) TestCheckBinlogHeaderExist(c *check.C) { // invalid data invalidData := make([]byte, len(replication.BinLogFileHeader)) copy(invalidData, replication.BinLogFileHeader) - invalidData[0] = invalidData[0] + 1 - err = ioutil.WriteFile(filename, invalidData, 0644) + invalidData[0]++ + err = ioutil.WriteFile(filename, invalidData, 0o644) c.Assert(err, check.IsNil) exist, err = checkBinlogHeaderExist(filename) c.Assert(err, check.ErrorMatches, ".*header not valid.*") @@ -104,14 +101,14 @@ func (t *testFileUtilSuite) TestCheckFormatDescriptionEventExist(c *check.C) { c.Assert(exist, check.IsFalse) // empty file - err = ioutil.WriteFile(filename, nil, 0644) + err = ioutil.WriteFile(filename, nil, 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(err, check.ErrorMatches, ".*no binlog file header at the beginning.*") c.Assert(exist, check.IsFalse) // only file header - err = ioutil.WriteFile(filename, replication.BinLogFileHeader, 0644) + err = ioutil.WriteFile(filename, replication.BinLogFileHeader, 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(err, check.IsNil) @@ -121,7 +118,7 @@ func (t *testFileUtilSuite) TestCheckFormatDescriptionEventExist(c *check.C) { var buff bytes.Buffer buff.Write(replication.BinLogFileHeader) buff.Write(formatDescEv.RawData[:replication.EventHeaderSize-1]) - err = ioutil.WriteFile(filename, buff.Bytes(), 0644) + err = ioutil.WriteFile(filename, buff.Bytes(), 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(errors.Cause(err), check.Equals, io.EOF) @@ -131,7 +128,7 @@ func (t *testFileUtilSuite) TestCheckFormatDescriptionEventExist(c *check.C) { buff.Reset() buff.Write(replication.BinLogFileHeader) buff.Write(formatDescEv.RawData[:replication.EventHeaderSize]) - err = ioutil.WriteFile(filename, buff.Bytes(), 0644) + err = ioutil.WriteFile(filename, buff.Bytes(), 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(err, check.ErrorMatches, ".*get event err EOF.*") @@ -141,7 +138,7 @@ func (t *testFileUtilSuite) TestCheckFormatDescriptionEventExist(c *check.C) { buff.Reset() buff.Write(replication.BinLogFileHeader) buff.Write(formatDescEv.RawData[:replication.EventHeaderSize+1]) - err = ioutil.WriteFile(filename, buff.Bytes(), 0644) + err = ioutil.WriteFile(filename, buff.Bytes(), 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(err, check.ErrorMatches, ".*get event err EOF.*") @@ -153,7 +150,7 @@ func (t *testFileUtilSuite) TestCheckFormatDescriptionEventExist(c *check.C) { buff.Write(formatDescEv.RawData) dataCopy := make([]byte, buff.Len()) copy(dataCopy, buff.Bytes()) - err = ioutil.WriteFile(filename, buff.Bytes(), 0644) + err = ioutil.WriteFile(filename, buff.Bytes(), 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(err, check.IsNil) @@ -161,7 +158,7 @@ func (t *testFileUtilSuite) TestCheckFormatDescriptionEventExist(c *check.C) { // more than the event buff.Write([]byte("more data")) - err = ioutil.WriteFile(filename, buff.Bytes(), 0644) + err = ioutil.WriteFile(filename, buff.Bytes(), 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(err, check.IsNil) @@ -173,7 +170,7 @@ func (t *testFileUtilSuite) TestCheckFormatDescriptionEventExist(c *check.C) { buff.Reset() buff.Write(replication.BinLogFileHeader) buff.Write(queryEv.RawData) - err = ioutil.WriteFile(filename, buff.Bytes(), 0644) + err = ioutil.WriteFile(filename, buff.Bytes(), 0o644) c.Assert(err, check.IsNil) exist, err = checkFormatDescriptionEventExist(filename) c.Assert(err, check.ErrorMatches, ".*expect FormatDescriptionEvent.*") @@ -217,7 +214,7 @@ func (t *testFileUtilSuite) TestCheckIsDuplicateEvent(c *check.C) { } // write the events to a file filename := filepath.Join(c.MkDir(), "test-mysql-bin.000001") - err = ioutil.WriteFile(filename, allData.Bytes(), 0644) + err = ioutil.WriteFile(filename, allData.Bytes(), 0o644) c.Assert(err, check.IsNil) // all events in the file @@ -322,7 +319,7 @@ func (t *testFileUtilSuite) testGetTxnPosGTIDs(c *check.C, filename, flavor, pre c.Assert(err, check.IsNil) // write the events to a file - err = ioutil.WriteFile(filename, baseData, 0644) + err = ioutil.WriteFile(filename, baseData, 0o644) c.Assert(err, check.IsNil) // not extra data exists @@ -356,7 +353,7 @@ func (t *testFileUtilSuite) testGetTxnPosGTIDs(c *check.C, filename, flavor, pre // write an incomplete event to the file corruptData := extraEvents[0].RawData[:len(extraEvents[0].RawData)-2] - f, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0644) + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0o644) c.Assert(err, check.IsNil) _, err = f.Write(corruptData) c.Assert(err, check.IsNil) @@ -369,7 +366,7 @@ func (t *testFileUtilSuite) testGetTxnPosGTIDs(c *check.C, filename, flavor, pre c.Assert(gSet, check.DeepEquals, expectedGTIDs) // truncate extra data - f, err = os.OpenFile(filename, os.O_WRONLY, 0644) + f, err = os.OpenFile(filename, os.O_WRONLY, 0o644) c.Assert(err, check.IsNil) err = f.Truncate(expectedPos) c.Assert(err, check.IsNil) @@ -377,7 +374,7 @@ func (t *testFileUtilSuite) testGetTxnPosGTIDs(c *check.C, filename, flavor, pre // write an incomplete transaction with some completed events for i := 0; i < len(extraEvents)-1; i++ { - f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0644) + f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0o644) c.Assert(err, check.IsNil) _, err = f.Write(extraEvents[i].RawData) // write the event c.Assert(err, check.IsNil) @@ -390,7 +387,7 @@ func (t *testFileUtilSuite) testGetTxnPosGTIDs(c *check.C, filename, flavor, pre } // write a completed event (and a completed transaction) to the file - f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0644) + f, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0o644) c.Assert(err, check.IsNil) _, err = f.Write(extraEvents[len(extraEvents)-1].RawData) // write the event c.Assert(err, check.IsNil) @@ -408,6 +405,7 @@ func (t *testFileUtilSuite) testGetTxnPosGTIDs(c *check.C, filename, flavor, pre // genBinlogEventsWithGTIDs generates some binlog events used by testFileUtilSuite and testFileWriterSuite. // now, its generated events including 3 DDL and 10 DML. +// nolint:unparam func genBinlogEventsWithGTIDs(c *check.C, flavor string, previousGTIDSet, latestGTID1, latestGTID2 gtid.Set) (*event.Generator, []*replication.BinlogEvent, []byte) { var ( serverID uint32 = 11 @@ -493,7 +491,7 @@ func (t *testFileUtilSuite) TestGetTxnPosGTIDsNoGTID(c *check.C) { latestPos = queryEv.Header.LogPos // write events to the file - f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0644) + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0o644) c.Assert(err, check.IsNil) _, err = f.Write(replication.BinLogFileHeader) c.Assert(err, check.IsNil) @@ -559,7 +557,7 @@ func (t *testFileUtilSuite) testGetTxnPosGTIDsIllegalGTID(c *check.C, gtidEv *re c.Assert(err, check.IsNil) // write events to the file - f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0644) + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0o644) c.Assert(err, check.IsNil) _, err = f.Write(replication.BinLogFileHeader) c.Assert(err, check.IsNil) @@ -604,7 +602,7 @@ func (t *testFileUtilSuite) testDontTruncate(c *check.C, events []*replication.B parser2 = parser.New() ) - f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0644) + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0o644) c.Assert(err, check.IsNil) _, err = f.Write(replication.BinLogFileHeader) diff --git a/syncer/causality.go b/syncer/causality.go index 8c0d1831bd..e0c5e750b5 100644 --- a/syncer/causality.go +++ b/syncer/causality.go @@ -64,7 +64,7 @@ func (c *causality) reset() { c.relations = make(map[string]string) } -// detectConflict detects whether there is a conflict +// detectConflict detects whether there is a conflict. func (c *causality) detectConflict(keys []string) bool { if len(keys) == 0 { return false diff --git a/syncer/checkpoint.go b/syncer/checkpoint.go index 89c7ff4c84..b3d4233b6b 100644 --- a/syncer/checkpoint.go +++ b/syncer/checkpoint.go @@ -136,14 +136,14 @@ func (b *binlogPoint) outOfDate() bool { return binlog.CompareLocation(b.location, b.flushedLocation, b.enableGTID) > 0 } -// MySQLLocation returns point as binlog.Location +// MySQLLocation returns point as binlog.Location. func (b *binlogPoint) MySQLLocation() binlog.Location { b.RLock() defer b.RUnlock() return b.location } -// FlushedMySQLLocation returns flushed point as binlog.Location +// FlushedMySQLLocation returns flushed point as binlog.Location. func (b *binlogPoint) FlushedMySQLLocation() binlog.Location { b.RLock() defer b.RUnlock() @@ -169,7 +169,7 @@ func (b *binlogPoint) String() string { // when save checkpoint, we must differ saving in memory from saving (flushing) to DB (or file) permanently // for sharding merging, we must save checkpoint in memory to support skip when re-syncing for the special streamer // but before all DDLs for a sharding group to be synced and executed, we should not save checkpoint permanently -// because, when restarting to continue the sync, all sharding DDLs must try-sync again +// because, when restarting to continue the sync, all sharding DDLs must try-sync again. type CheckPoint interface { // Init initializes the CheckPoint Init(tctx *tcontext.Context) error @@ -251,7 +251,7 @@ type CheckPoint interface { // RemoteCheckPoint implements CheckPoint // which using target database to store info // NOTE: now we sync from relay log, so not add GTID support yet -// it's not thread-safe +// it's not thread-safe. type RemoteCheckPoint struct { sync.RWMutex @@ -286,7 +286,7 @@ type RemoteCheckPoint struct { logCtx *tcontext.Context } -// NewRemoteCheckPoint creates a new RemoteCheckPoint +// NewRemoteCheckPoint creates a new RemoteCheckPoint. func NewRemoteCheckPoint(tctx *tcontext.Context, cfg *config.SubTaskConfig, id string) CheckPoint { cp := &RemoteCheckPoint{ cfg: cfg, @@ -300,7 +300,7 @@ func NewRemoteCheckPoint(tctx *tcontext.Context, cfg *config.SubTaskConfig, id s return cp } -// Init implements CheckPoint.Init +// Init implements CheckPoint.Init. func (cp *RemoteCheckPoint) Init(tctx *tcontext.Context) error { checkPointDB := cp.cfg.To checkPointDB.RawDBCfg = config.DefaultRawDBConfig().SetReadTimeout(maxCheckPointTimeout) @@ -314,17 +314,17 @@ func (cp *RemoteCheckPoint) Init(tctx *tcontext.Context) error { return cp.prepare(tctx) } -// Close implements CheckPoint.Close +// Close implements CheckPoint.Close. func (cp *RemoteCheckPoint) Close() { closeBaseDB(cp.logCtx, cp.db) } -// ResetConn implements CheckPoint.ResetConn +// ResetConn implements CheckPoint.ResetConn. func (cp *RemoteCheckPoint) ResetConn(tctx *tcontext.Context) error { return cp.dbConn.resetConn(tctx) } -// Clear implements CheckPoint.Clear +// Clear implements CheckPoint.Clear. func (cp *RemoteCheckPoint) Clear(tctx *tcontext.Context) error { cp.Lock() defer cp.Unlock() @@ -350,14 +350,14 @@ func (cp *RemoteCheckPoint) Clear(tctx *tcontext.Context) error { return nil } -// SaveTablePoint implements CheckPoint.SaveTablePoint +// SaveTablePoint implements CheckPoint.SaveTablePoint. func (cp *RemoteCheckPoint) SaveTablePoint(sourceSchema, sourceTable string, point binlog.Location, ti *model.TableInfo) { cp.Lock() defer cp.Unlock() cp.saveTablePoint(sourceSchema, sourceTable, point, ti) } -// saveTablePoint saves single table's checkpoint without mutex.Lock +// saveTablePoint saves single table's checkpoint without mutex.Lock. func (cp *RemoteCheckPoint) saveTablePoint(sourceSchema, sourceTable string, location binlog.Location, ti *model.TableInfo) { if binlog.CompareLocation(cp.globalPoint.location, location, cp.cfg.EnableGTID) > 0 { panic(fmt.Sprintf("table checkpoint %+v less than global checkpoint %+v", location, cp.globalPoint)) @@ -379,17 +379,17 @@ func (cp *RemoteCheckPoint) saveTablePoint(sourceSchema, sourceTable string, loc } // SaveSafeModeExitPoint implements CheckPoint.SaveSafeModeExitPoint -// shouldn't call concurrently (only called before loop in Syncer.Run and in loop to reset) +// shouldn't call concurrently (only called before loop in Syncer.Run and in loop to reset). func (cp *RemoteCheckPoint) SaveSafeModeExitPoint(point *binlog.Location) { cp.safeModeExitPoint = point } -// SafeModeExitPoint implements CheckPoint.SafeModeExitPoint +// SafeModeExitPoint implements CheckPoint.SafeModeExitPoint. func (cp *RemoteCheckPoint) SafeModeExitPoint() *binlog.Location { return cp.safeModeExitPoint } -// DeleteTablePoint implements CheckPoint.DeleteTablePoint +// DeleteTablePoint implements CheckPoint.DeleteTablePoint. func (cp *RemoteCheckPoint) DeleteTablePoint(tctx *tcontext.Context, sourceSchema, sourceTable string) error { cp.Lock() defer cp.Unlock() @@ -418,7 +418,7 @@ func (cp *RemoteCheckPoint) DeleteTablePoint(tctx *tcontext.Context, sourceSchem return nil } -// DeleteSchemaPoint implements CheckPoint.DeleteSchemaPoint +// DeleteSchemaPoint implements CheckPoint.DeleteSchemaPoint. func (cp *RemoteCheckPoint) DeleteSchemaPoint(tctx *tcontext.Context, sourceSchema string) error { cp.Lock() defer cp.Unlock() @@ -473,7 +473,7 @@ func (cp *RemoteCheckPoint) IsNewerTablePoint(sourceSchema, sourceTable string, return binlog.CompareLocation(location, oldLocation, cp.cfg.EnableGTID) > 0 } -// SaveGlobalPoint implements CheckPoint.SaveGlobalPoint +// SaveGlobalPoint implements CheckPoint.SaveGlobalPoint. func (cp *RemoteCheckPoint) SaveGlobalPoint(location binlog.Location) { cp.Lock() defer cp.Unlock() @@ -484,7 +484,7 @@ func (cp *RemoteCheckPoint) SaveGlobalPoint(location binlog.Location) { } } -// FlushPointsExcept implements CheckPoint.FlushPointsExcept +// FlushPointsExcept implements CheckPoint.FlushPointsExcept. func (cp *RemoteCheckPoint) FlushPointsExcept(tctx *tcontext.Context, exceptTables [][]string, extraSQLs []string, extraArgs [][]interface{}) error { cp.RLock() defer cp.RUnlock() @@ -557,7 +557,7 @@ func (cp *RemoteCheckPoint) FlushPointsExcept(tctx *tcontext.Context, exceptTabl return nil } -// FlushPointWithTableInfo implements CheckPoint.FlushPointWithTableInfo +// FlushPointWithTableInfo implements CheckPoint.FlushPointWithTableInfo. func (cp *RemoteCheckPoint) FlushPointWithTableInfo(tctx *tcontext.Context, sourceSchema string, sourceTable string, ti *model.TableInfo) error { cp.Lock() defer cp.Unlock() @@ -594,7 +594,7 @@ func (cp *RemoteCheckPoint) FlushPointWithTableInfo(tctx *tcontext.Context, sour return nil } -// GlobalPoint implements CheckPoint.GlobalPoint +// GlobalPoint implements CheckPoint.GlobalPoint. func (cp *RemoteCheckPoint) GlobalPoint() binlog.Location { cp.RLock() defer cp.RUnlock() @@ -602,7 +602,7 @@ func (cp *RemoteCheckPoint) GlobalPoint() binlog.Location { return cp.globalPoint.MySQLLocation() } -// TablePoint implements CheckPoint.TablePoint +// TablePoint implements CheckPoint.TablePoint. func (cp *RemoteCheckPoint) TablePoint() map[string]map[string]binlog.Location { cp.RLock() defer cp.RUnlock() @@ -617,7 +617,7 @@ func (cp *RemoteCheckPoint) TablePoint() map[string]map[string]binlog.Location { return tablePoint } -// FlushedGlobalPoint implements CheckPoint.FlushedGlobalPoint +// FlushedGlobalPoint implements CheckPoint.FlushedGlobalPoint. func (cp *RemoteCheckPoint) FlushedGlobalPoint() binlog.Location { cp.RLock() defer cp.RUnlock() @@ -625,7 +625,7 @@ func (cp *RemoteCheckPoint) FlushedGlobalPoint() binlog.Location { return cp.globalPoint.FlushedMySQLLocation() } -// String implements CheckPoint.String +// String implements CheckPoint.String. func (cp *RemoteCheckPoint) String() string { cp.RLock() defer cp.RUnlock() @@ -633,14 +633,14 @@ func (cp *RemoteCheckPoint) String() string { return cp.globalPoint.String() } -// CheckGlobalPoint implements CheckPoint.CheckGlobalPoint +// CheckGlobalPoint implements CheckPoint.CheckGlobalPoint. func (cp *RemoteCheckPoint) CheckGlobalPoint() bool { cp.RLock() defer cp.RUnlock() return time.Since(cp.globalPointSaveTime) >= time.Duration(cp.cfg.CheckpointFlushInterval)*time.Second } -// Rollback implements CheckPoint.Rollback +// Rollback implements CheckPoint.Rollback. func (cp *RemoteCheckPoint) Rollback(schemaTracker *schema.Tracker) { cp.RLock() defer cp.RUnlock() @@ -726,7 +726,7 @@ func (cp *RemoteCheckPoint) createTable(tctx *tcontext.Context) error { return err } -// Load implements CheckPoint.Load +// Load implements CheckPoint.Load. func (cp *RemoteCheckPoint) Load(tctx *tcontext.Context) error { cp.Lock() defer cp.Unlock() @@ -835,7 +835,7 @@ func (cp *RemoteCheckPoint) Load(tctx *tcontext.Context) error { return terror.WithScope(terror.DBErrorAdapt(rows.Err(), terror.ErrDBDriverError), terror.ScopeDownstream) } -// LoadMeta implements CheckPoint.LoadMeta +// LoadMeta implements CheckPoint.LoadMeta. func (cp *RemoteCheckPoint) LoadMeta() error { cp.Lock() defer cp.Unlock() @@ -891,7 +891,7 @@ func (cp *RemoteCheckPoint) LoadMeta() error { return nil } -// genUpdateSQL generates SQL and arguments for update checkpoint +// genUpdateSQL generates SQL and arguments for update checkpoint. func (cp *RemoteCheckPoint) genUpdateSQL(cpSchema, cpTable string, location binlog.Location, safeModeExitLoc *binlog.Location, tiBytes []byte, isGlobal bool) (string, []interface{}) { // use `INSERT INTO ... ON DUPLICATE KEY UPDATE` rather than `REPLACE INTO` // to keep `create_time`, `update_time` correctly @@ -930,8 +930,10 @@ func (cp *RemoteCheckPoint) genUpdateSQL(cpSchema, cpTable string, location binl } // convert tiBytes to string to get a readable log - args := []interface{}{cp.id, cpSchema, cpTable, location.Position.Name, location.Position.Pos, location.GTIDSetStr(), - exitSafeName, exitSafePos, exitSafeGTIDStr, string(tiBytes), isGlobal} + args := []interface{}{ + cp.id, cpSchema, cpTable, location.Position.Name, location.Position.Pos, location.GTIDSetStr(), + exitSafeName, exitSafePos, exitSafeGTIDStr, string(tiBytes), isGlobal, + } return sql2, args } @@ -951,7 +953,7 @@ func (cp *RemoteCheckPoint) parseMetaData() (*binlog.Location, *binlog.Location, return loc, loc2, err } -// GetFlushedTableInfo implements CheckPoint.GetFlushedTableInfo +// GetFlushedTableInfo implements CheckPoint.GetFlushedTableInfo. func (cp *RemoteCheckPoint) GetFlushedTableInfo(schema string, table string) *model.TableInfo { cp.Lock() defer cp.Unlock() diff --git a/syncer/checkpoint_test.go b/syncer/checkpoint_test.go index 3f72f22a30..f2172d162b 100644 --- a/syncer/checkpoint_test.go +++ b/syncer/checkpoint_test.go @@ -95,7 +95,7 @@ func (s *testCheckpointSuite) prepareCheckPointSQL() { deleteSchemaPointSQL = fmt.Sprintf("DELETE FROM %s WHERE id = \\? AND cp_schema = \\?", dbutil.TableName(s.cfg.MetaSchema, cputil.SyncerCheckpoint(s.cfg.Name))) } -// this test case uses sqlmock to simulate all SQL operations in tests +// this test case uses sqlmock to simulate all SQL operations in tests. func (s *testCheckpointSuite) TestCheckPoint(c *C) { tctx := tcontext.Background() @@ -264,7 +264,7 @@ func (s *testCheckpointSuite) testGlobalCheckPoint(c *C, cp CheckPoint) { filename := filepath.Join(dir, "metadata") err = ioutil.WriteFile(filename, []byte( fmt.Sprintf("SHOW MASTER STATUS:\n\tLog: %s\n\tPos: %d\n\tGTID:\n\nSHOW SLAVE STATUS:\n\tHost: %s\n\tLog: %s\n\tPos: %d\n\tGTID:\n\n", pos1.Name, pos1.Pos, "slave_host", pos1.Name, pos1.Pos+1000)), - 0644) + 0o644) c.Assert(err, IsNil) s.cfg.Mode = config.ModeAll s.cfg.Dir = dir @@ -305,7 +305,7 @@ SHOW MASTER STATUS: /* AFTER CONNECTION POOL ESTABLISHED */ Log: %s Pos: %d GTID: -`, pos1.Name, pos1.Pos, "slave_host", pos1.Name, pos1.Pos+1000, pos2.Name, pos2.Pos)), 0644) +`, pos1.Name, pos1.Pos, "slave_host", pos1.Name, pos1.Pos+1000, pos2.Name, pos2.Pos)), 0o644) c.Assert(err, IsNil) c.Assert(cp.LoadMeta(), IsNil) @@ -475,5 +475,4 @@ func (s *testCheckpointSuite) testTableCheckPoint(c *C, cp CheckPoint) { c.Assert(rcp.points[schema][table].TableInfo(), NotNil) c.Assert(rcp.points[schema][table].flushedTI, NotNil) c.Assert(*rcp.safeModeExitPoint, DeepEquals, binlog.InitLocation(pos2, gs)) - } diff --git a/syncer/db.go b/syncer/db.go index 2f771aa7b2..4e8aad91d2 100644 --- a/syncer/db.go +++ b/syncer/db.go @@ -59,7 +59,7 @@ func createBaseDB(dbCfg config.DBConfig) (*conn.BaseDB, error) { return db, nil } -// close baseDB to release all connection generated by this baseDB and this baseDB +// close baseDB to release all connection generated by this baseDB and this baseDB. func closeBaseDB(logCtx *tcontext.Context, baseDB *conn.BaseDB) { if baseDB != nil { err := baseDB.Close() @@ -72,7 +72,7 @@ func closeBaseDB(logCtx *tcontext.Context, baseDB *conn.BaseDB) { // UpStreamConn connect to upstream DB // Normally, we need to get some upstream information through some helper functions // these helper functions are all easy query functions, so we use a pool of connections here -// maybe change to one connection some day +// maybe change to one connection some day. type UpStreamConn struct { BaseDB *conn.BaseDB } @@ -123,7 +123,7 @@ func closeUpstreamConn(tctx *tcontext.Context, conn *UpStreamConn) { } // DBConn represents a live DB connection -// it's not thread-safe +// it's not thread-safe. type DBConn struct { cfg *config.SubTaskConfig baseConn *conn.BaseConn @@ -132,7 +132,7 @@ type DBConn struct { resetBaseConnFn func(*tcontext.Context, *conn.BaseConn) (*conn.BaseConn, error) } -// resetConn reset one worker connection from specify *BaseDB +// resetConn reset one worker connection from specify *BaseDB. func (conn *DBConn) resetConn(tctx *tcontext.Context) error { baseConn, err := conn.resetBaseConnFn(tctx, conn.baseConn) if err != nil { @@ -146,6 +146,7 @@ func (conn *DBConn) querySQL(tctx *tcontext.Context, query string, args ...inter if conn == nil || conn.baseConn == nil { return nil, terror.ErrDBUnExpect.Generate("database base connection not valid") } + // nolint:dupl params := retry.Params{ RetryCount: 10, FirstRetryDuration: retryTimeout, @@ -182,6 +183,9 @@ func (conn *DBConn) querySQL(tctx *tcontext.Context, query string, args ...inter startTime := time.Now() ret, err := conn.baseConn.QuerySQL(ctx, query, args...) if err == nil { + if ret.Err() != nil { + return err, ret.Err() + } cost := time.Since(startTime) queryHistogram.WithLabelValues(conn.cfg.Name).Observe(cost.Seconds()) if cost.Seconds() > 1 { @@ -194,7 +198,6 @@ func (conn *DBConn) querySQL(tctx *tcontext.Context, query string, args ...inter return ret, err }, ) - if err != nil { tctx.L().ErrorFilterContextCanceled("query statement failed after retry", zap.String("query", utils.TruncateString(query, -1)), @@ -222,6 +225,7 @@ func (conn *DBConn) executeSQLWithIgnore(tctx *tcontext.Context, ignoreError fun return 0, terror.ErrDBUnExpect.Generate("database base connection not valid") } + // nolint:dupl params := retry.Params{ RetryCount: 100, FirstRetryDuration: retryTimeout, @@ -269,7 +273,6 @@ func (conn *DBConn) executeSQLWithIgnore(tctx *tcontext.Context, ignoreError fun } return ret, err }) - if err != nil { tctx.L().ErrorFilterContextCanceled("execute statements failed after retry", zap.String("queries", utils.TruncateInterface(queries, -1)), @@ -316,11 +319,12 @@ func countBinaryLogsSize(fromFile mysql.Position, db *sql.DB) (int64, error) { var total int64 for _, file := range files { - if file.name < fromFile.Name { + switch { + case file.name < fromFile.Name: continue - } else if file.name > fromFile.Name { + case file.name > fromFile.Name: total += file.size - } else if file.name == fromFile.Name { + case file.name == fromFile.Name: if file.size > int64(fromFile.Pos) { total += file.size - int64(fromFile.Pos) } diff --git a/syncer/db_test.go b/syncer/db_test.go index 0e1d24632e..708eb6f315 100644 --- a/syncer/db_test.go +++ b/syncer/db_test.go @@ -216,7 +216,7 @@ func (s *testDBSuite) TestTimezone(c *C) { "America/Phoenix", }, } - queryTs := "select unix_timestamp(a) from `tztest_1`.`t_1` where id = ?" + queryTS := "select unix_timestamp(a) from `tztest_1`.`t_1` where id = ?" dropSQLs := []string{ "drop table tztest_1.t_1", @@ -280,7 +280,7 @@ func (s *testDBSuite) TestTimezone(c *C) { rowid := ev.Rows[0][0].(int32) var ts sql.NullInt64 - err2 := s.db.QueryRow(queryTs, rowid).Scan(&ts) + err2 := s.db.QueryRow(queryTS, rowid).Scan(&ts) c.Assert(err2, IsNil) c.Assert(ts.Valid, IsTrue) diff --git a/syncer/ddl.go b/syncer/ddl.go index 5803fd49c8..9e66c48563 100644 --- a/syncer/ddl.go +++ b/syncer/ddl.go @@ -26,7 +26,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// parseDDLResult represents the result of parseDDLSQL +// parseDDLResult represents the result of parseDDLSQL. type parseDDLResult struct { stmt ast.StmtNode ignore bool @@ -113,10 +113,10 @@ func (s *Syncer) parseDDLSQL(sql string, p *parser.Parser, schema string) (resul } } -/// resolveDDLSQL do two things +// resolveDDLSQL do two things // * it splits multiple operations in one DDL statement into multiple DDL statements // * try to apply online ddl by given online -// return @spilt sqls, @online ddl table names, @error +// return @spilt sqls, @online ddl table names, @error. func (s *Syncer) resolveDDLSQL(tctx *tcontext.Context, p *parser.Parser, stmt ast.StmtNode, schema string) (sqls []string, tables map[string]*filter.Table, err error) { sqls, err = parserpkg.SplitDDL(stmt, schema) if err != nil { @@ -178,7 +178,7 @@ func (s *Syncer) handleDDL(p *parser.Parser, schema, sql string) (string, [][]*f } // handle online ddls -// if sql is online ddls, we would find it's ghost table, and ghost ddls, then replay its table name by real table name +// if sql is online ddls, we would find it's ghost table, and ghost ddls, then replay its table name by real table name. func (s *Syncer) handleOnlineDDL(tctx *tcontext.Context, p *parser.Parser, schema, sql string) ([]string, *filter.Table, error) { if s.onlineDDL == nil { return []string{sql}, nil, nil diff --git a/syncer/ddl_test.go b/syncer/ddl_test.go index dced261f03..1710a50214 100644 --- a/syncer/ddl_test.go +++ b/syncer/ddl_test.go @@ -451,8 +451,10 @@ func (s *testSyncerSuite) TestDropSchemaInSharding(c *C) { clone, _ := s.cfg.Clone() clone.ShardMode = config.ShardPessimistic syncer := NewSyncer(clone, nil) + // nolint:dogsled _, _, _, _, err := syncer.sgk.AddGroup(targetDB, targetTbl, []string{source1}, nil, true) c.Assert(err, IsNil) + // nolint:dogsled _, _, _, _, err = syncer.sgk.AddGroup(targetDB, targetTbl, []string{source2}, nil, true) c.Assert(err, IsNil) c.Assert(syncer.sgk.Groups(), HasLen, 2) @@ -514,8 +516,10 @@ func (s *testSyncerSuite) TestClearOnlineDDL(c *C) { } syncer.onlineDDL = mock + // nolint:dogsled _, _, _, _, err := syncer.sgk.AddGroup(targetDB, targetTbl, []string{source1}, nil, true) c.Assert(err, IsNil) + // nolint:dogsled _, _, _, _, err = syncer.sgk.AddGroup(targetDB, targetTbl, []string{source2}, nil, true) c.Assert(err, IsNil) diff --git a/syncer/dml.go b/syncer/dml.go index 8b5f19f0a4..4fb206d830 100644 --- a/syncer/dml.go +++ b/syncer/dml.go @@ -29,7 +29,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// genDMLParam stores pruned columns, data as well as the original columns, data, index +// genDMLParam stores pruned columns, data as well as the original columns, data, index. type genDMLParam struct { schema string table string @@ -60,7 +60,7 @@ func genInsertSQLs(param *genDMLParam) ([]string, [][]string, [][]interface{}, e values = make([][]interface{}, 0, len(dataSeq)) ) - var insertOrReplace = "INSERT INTO" + insertOrReplace := "INSERT INTO" if param.safeMode { insertOrReplace = "REPLACE INTO" } @@ -72,7 +72,7 @@ func genInsertSQLs(param *genDMLParam) ([]string, [][]string, [][]interface{}, e } value := extractValueFromData(data, columns) - var originalValue = value + originalValue := value if len(columns) != len(ti.Columns) { originalValue = extractValueFromData(originalDataSeq[dataIdx], ti.Columns) } @@ -352,7 +352,7 @@ func columnValue(value interface{}, ft *types.FieldType) string { case float32: data = strconv.FormatFloat(float64(v), 'f', -1, 32) case float64: - data = strconv.FormatFloat(float64(v), 'f', -1, 64) + data = strconv.FormatFloat(v, 'f', -1, 64) case string: data = v case []byte: diff --git a/syncer/dml_test.go b/syncer/dml_test.go index aa92cca23a..675959e0f1 100644 --- a/syncer/dml_test.go +++ b/syncer/dml_test.go @@ -37,9 +37,9 @@ func (s *testSyncerSuite) TestCastUnsigned(c *C) { }{ {int8(-math.Exp2(7)), false, mysql.TypeTiny, int8(-math.Exp2(7))}, // TINYINT {int8(-math.Exp2(7)), true, mysql.TypeTiny, uint8(math.Exp2(7))}, - {int16(-math.Exp2(15)), false, mysql.TypeShort, int16(-math.Exp2(15))}, //SMALLINT + {int16(-math.Exp2(15)), false, mysql.TypeShort, int16(-math.Exp2(15))}, // SMALLINT {int16(-math.Exp2(15)), true, mysql.TypeShort, uint16(math.Exp2(15))}, - {int32(-math.Exp2(23)), false, mysql.TypeInt24, int32(-math.Exp2(23))}, //MEDIUMINT + {int32(-math.Exp2(23)), false, mysql.TypeInt24, int32(-math.Exp2(23))}, // MEDIUMINT {int32(-math.Exp2(23)), true, mysql.TypeInt24, uint32(math.Exp2(23))}, {int32(-math.Exp2(31)), false, mysql.TypeLong, int32(-math.Exp2(31))}, // INT {int32(-math.Exp2(31)), true, mysql.TypeLong, uint32(math.Exp2(31))}, @@ -211,8 +211,9 @@ func (s *testSyncerSuite) TestGenMultipleKeys(c *C) { } for i, tc := range testCases { + schema := tc.schema assert := func(obtained interface{}, checker Checker, args ...interface{}) { - c.Assert(obtained, checker, append(args, Commentf("test case schema: %s", tc.schema))...) + c.Assert(obtained, checker, append(args, Commentf("test case schema: %s", schema))...) } ti, err := createTableInfo(p, se, int64(i+1), tc.schema) diff --git a/syncer/err-operator/operator.go b/syncer/err-operator/operator.go index 33aa1bafc8..b019d13ea9 100644 --- a/syncer/err-operator/operator.go +++ b/syncer/err-operator/operator.go @@ -30,14 +30,14 @@ import ( ) // Operator contains an operation for specified binlog pos -// used by `handle-error` +// used by `handle-error`. type Operator struct { uuid string // add a UUID, make it more friendly to be traced in log op pb.ErrorOp events []*replication.BinlogEvent // startLocation -> events } -// newOperator creates a new operator with a random UUID +// newOperator creates a new operator with a random UUID. func newOperator(op pb.ErrorOp, events []*replication.BinlogEvent) *Operator { return &Operator{ uuid: uuid.New().String(), @@ -56,14 +56,14 @@ func (o *Operator) String() string { return fmt.Sprintf("uuid: %s, op: %s, events: %s", o.uuid, o.op, strings.Join(events, "\n")) } -// Holder holds error operator +// Holder holds error operator. type Holder struct { mu sync.Mutex operators map[string]*Operator logger log.Logger } -// NewHolder creates a new Holder +// NewHolder creates a new Holder. func NewHolder(pLogger *log.Logger) *Holder { return &Holder{ operators: make(map[string]*Operator), @@ -71,7 +71,7 @@ func NewHolder(pLogger *log.Logger) *Holder { } } -// Set sets an Operator +// Set sets an Operator. func (h *Holder) Set(pos string, op pb.ErrorOp, events []*replication.BinlogEvent) error { h.mu.Lock() defer h.mu.Unlock() @@ -102,7 +102,7 @@ func (h *Holder) Set(pos string, op pb.ErrorOp, events []*replication.BinlogEven // replace event a 1010, 0 1010, 1 // replace event b 1010, 1 1010, 2 // replace event c 1010, 2 1020, 0 -// event 3 1020, 0 1030, 0 +// event 3 1020, 0 1030, 0. func (h *Holder) GetEvent(startLocation binlog.Location) (*replication.BinlogEvent, error) { h.mu.Lock() defer h.mu.Unlock() @@ -125,7 +125,7 @@ func (h *Holder) GetEvent(startLocation binlog.Location) (*replication.BinlogEve return e, nil } -// MatchAndApply tries to match operation for event by location and apply it on replace events +// MatchAndApply tries to match operation for event by location and apply it on replace events. func (h *Holder) MatchAndApply(startLocation, endLocation binlog.Location) (bool, pb.ErrorOp) { h.mu.Lock() defer h.mu.Unlock() @@ -168,7 +168,7 @@ func (h *Holder) MatchAndApply(startLocation, endLocation binlog.Location) (bool return true, operator.op } -// RemoveOutdated remove outdated operator +// RemoveOutdated remove outdated operator. func (h *Holder) RemoveOutdated(flushLocation binlog.Location) error { h.mu.Lock() defer h.mu.Unlock() diff --git a/syncer/err-operator/operator_test.go b/syncer/err-operator/operator_test.go index 1b4a29e88e..c09118c93b 100644 --- a/syncer/err-operator/operator_test.go +++ b/syncer/err-operator/operator_test.go @@ -32,8 +32,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testOperatorSuite struct { -} +type testOperatorSuite struct{} func (o *testOperatorSuite) TestOperator(c *C) { logger := log.L() @@ -43,7 +42,8 @@ func (o *testOperatorSuite) TestOperator(c *C) { Position: mysql.Position{ Name: "mysql-bin.000001", Pos: 233, - }} + }, + } endLocation := binlog.Location{ Position: mysql.Position{ Name: "mysql-bin.000001", diff --git a/syncer/error.go b/syncer/error.go index a36fa68d03..039e65c3f1 100644 --- a/syncer/error.go +++ b/syncer/error.go @@ -136,14 +136,15 @@ func (s *Syncer) handleSpecialDDLError(tctx *tcontext.Context, err error, ddls [ table string col string ) - if n, ok := stmt.(*ast.AlterTableStmt); !ok { + n, ok := stmt.(*ast.AlterTableStmt) + switch { + case !ok: return originErr - // support ALTER TABLE tbl_name DROP - } else if len(n.Specs) != 1 { + case len(n.Specs) != 1: return originErr - } else if n.Specs[0].Tp != ast.AlterTableDropColumn { + case n.Specs[0].Tp != ast.AlterTableDropColumn: return originErr - } else { + default: schema = n.Table.Schema.O table = n.Table.Name.O col = n.Specs[0].OldColumnName.Name.O @@ -165,11 +166,15 @@ func (s *Syncer) handleSpecialDDLError(tctx *tcontext.Context, err error, ddls [ ) for rows.Next() { if err2 = rows.Scan(&idx); err2 != nil { + // nolint:sqlclosecheck rows.Close() return originErr } idx2Check = append(idx2Check, idx) } + if rows.Err() != nil { + return rows.Err() + } // Close is idempotent, we could close in advance to reuse conn rows.Close() @@ -179,10 +184,14 @@ func (s *Syncer) handleSpecialDDLError(tctx *tcontext.Context, err error, ddls [ if err2 != nil || !rows.Next() || rows.Scan(&count) != nil || count != 1 { tctx.L().Warn("can't auto drop index", zap.String("index", idx)) if rows != nil { + // nolint: sqlclosecheck rows.Close() } return originErr } + if rows.Err() != nil { + return rows.Err() + } idx2Drop = append(idx2Drop, idx) rows.Close() } diff --git a/syncer/error_test.go b/syncer/error_test.go index 6a2196e354..d63116548a 100644 --- a/syncer/error_test.go +++ b/syncer/error_test.go @@ -203,5 +203,4 @@ func (s *testSyncerSuite) TestHandleSpecialDDLError(c *C) { handledErr = syncer.handleSpecialDDLError(tctx, execErr, ddls, 0, conn2) c.Assert(mock.ExpectationsWereMet(), IsNil) c.Assert(handledErr, Equals, execErr) - } diff --git a/syncer/filter_test.go b/syncer/filter_test.go index 5dce9f42cc..be89f36738 100644 --- a/syncer/filter_test.go +++ b/syncer/filter_test.go @@ -109,8 +109,8 @@ END`, true}, {"revoke reload on *.* from 't2'@'%'", true}, } - //filter, err := bf.NewBinlogEvent(nil) - //c.Assert(err, IsNil) + // filter, err := bf.NewBinlogEvent(nil) + // c.Assert(err, IsNil) syncer := &Syncer{} for _, t := range cases { skipped, err := syncer.skipQuery(nil, nil, t.sql) diff --git a/syncer/ghost.go b/syncer/ghost.go index 12b9d5a30a..1f12f1959b 100644 --- a/syncer/ghost.go +++ b/syncer/ghost.go @@ -29,12 +29,12 @@ import ( // Ghost handles gh-ost online ddls (not complete, don't need to review it) // _*_gho ghost table // _*_ghc ghost changelog table -// _*_del ghost transh table +// _*_del ghost transh table. type Ghost struct { storge *OnlineDDLStorage } -// NewGhost returns gh-oat online plugin +// NewGhost returns gh-oat online plugin. func NewGhost(tctx *tcontext.Context, cfg *config.SubTaskConfig) (OnlinePlugin, error) { g := &Ghost{ storge: NewOnlineDDLStorage(tcontext.Background().WithLogger(tctx.L().WithFields(zap.String("online ddl", "gh-ost"))), cfg), // create a context for logger @@ -44,7 +44,8 @@ func NewGhost(tctx *tcontext.Context, cfg *config.SubTaskConfig) (OnlinePlugin, } // Apply implements interface. -// returns ddls, real schema, real table, error +// returns ddls, real schema, real table, error. +// nolint:dupl func (g *Ghost) Apply(tctx *tcontext.Context, tables []*filter.Table, statement string, stmt ast.StmtNode) ([]string, string, string, error) { if len(tables) < 1 { return nil, "", "", terror.ErrSyncerUnitGhostApplyEmptyTable.Generate() @@ -56,8 +57,7 @@ func (g *Ghost) Apply(tctx *tcontext.Context, tables []*filter.Table, statement switch tp { case realTable: - switch stmt.(type) { - case *ast.RenameTableStmt: + if _, ok := stmt.(*ast.RenameTableStmt); ok { if len(tables) != parserpkg.SingleRenameTableNameNum { return nil, "", "", terror.ErrSyncerUnitGhostRenameTableNotValid.Generate() } @@ -72,8 +72,7 @@ func (g *Ghost) Apply(tctx *tcontext.Context, tables []*filter.Table, statement return []string{statement}, schema, table, nil case trashTable: // ignore trashTable - switch stmt.(type) { - case *ast.RenameTableStmt: + if _, ok := stmt.(*ast.RenameTableStmt); ok { if len(tables) != parserpkg.SingleRenameTableNameNum { return nil, "", "", terror.ErrSyncerUnitGhostRenameTableNotValid.Generate() } @@ -129,7 +128,7 @@ func (g *Ghost) Apply(tctx *tcontext.Context, tables []*filter.Table, statement return nil, schema, table, nil } -// Finish implements interface +// Finish implements interface. func (g *Ghost) Finish(tctx *tcontext.Context, schema, table string) error { if g == nil { return nil @@ -138,7 +137,7 @@ func (g *Ghost) Finish(tctx *tcontext.Context, schema, table string) error { return g.storge.Delete(tctx, schema, table) } -// TableType implements interface +// TableType implements interface. func (g *Ghost) TableType(table string) TableType { // 5 is _ _gho/ghc/del if len(table) > 5 && table[0] == '_' { @@ -154,7 +153,7 @@ func (g *Ghost) TableType(table string) TableType { return realTable } -// RealName implements interface +// RealName implements interface. func (g *Ghost) RealName(schema, table string) (string, string) { tp := g.TableType(table) if tp == trashTable || tp == ghostTable { @@ -164,17 +163,17 @@ func (g *Ghost) RealName(schema, table string) (string, string) { return schema, table } -// Clear clears online ddl information +// Clear clears online ddl information. func (g *Ghost) Clear(tctx *tcontext.Context) error { return g.storge.Clear(tctx) } -// Close implements interface +// Close implements interface. func (g *Ghost) Close() { g.storge.Close() } -// ResetConn implements interface +// ResetConn implements interface. func (g *Ghost) ResetConn(tctx *tcontext.Context) error { return g.storge.ResetConn(tctx) } diff --git a/syncer/handle_error.go b/syncer/handle_error.go index 03fe614be0..4851c357cc 100644 --- a/syncer/handle_error.go +++ b/syncer/handle_error.go @@ -28,7 +28,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -// HandleError handle error for syncer +// HandleError handle error for syncer. func (s *Syncer) HandleError(ctx context.Context, req *pb.HandleWorkerErrorRequest) error { pos := req.BinlogPos @@ -107,7 +107,7 @@ func (s *Syncer) genEvents(ctx context.Context, sqls []string) ([]*replication.B return events, nil } -// genQueryEvent generate QueryEvent with empty EventSize and LogPos +// genQueryEvent generate QueryEvent with empty EventSize and LogPos. func genQueryEvent(schema, query []byte) *replication.BinlogEvent { header := &replication.EventHeader{ EventType: replication.QUERY_EVENT, diff --git a/syncer/handle_error_test.go b/syncer/handle_error_test.go index bbc74c6fa3..249a25b064 100644 --- a/syncer/handle_error_test.go +++ b/syncer/handle_error_test.go @@ -18,6 +18,7 @@ import ( "fmt" . "github.com/pingcap/check" + "github.com/pingcap/dm/dm/pb" ) diff --git a/syncer/heartbeat.go b/syncer/heartbeat.go index 518b29b959..1e144f1ec7 100644 --- a/syncer/heartbeat.go +++ b/syncer/heartbeat.go @@ -58,7 +58,7 @@ type HeartbeatConfig struct { primaryCfg config.DBConfig // primary server's DBConfig } -// Equal tests whether config equals to other +// Equal tests whether config equals to other. func (cfg *HeartbeatConfig) Equal(other *HeartbeatConfig) error { if other.updateInterval != 0 && other.updateInterval != cfg.updateInterval { return terror.ErrSyncerUnitHeartbeatCheckConfig.Generatef("updateInterval not equal, self: %d, other: %d", cfg.updateInterval, other.updateInterval) @@ -85,7 +85,7 @@ type Heartbeat struct { table string // for which table the heartbeat table belongs to primary *conn.BaseDB - secondaryTs map[string]float64 // task-name => secondary (syncer) ts + secondaryTS map[string]float64 // task-name => secondary (syncer) ts cancel context.CancelFunc wg sync.WaitGroup @@ -93,7 +93,7 @@ type Heartbeat struct { logger log.Logger } -// GetHeartbeat gets singleton instance of Heartbeat +// GetHeartbeat gets singleton instance of Heartbeat. func GetHeartbeat(cfg *HeartbeatConfig) (*Heartbeat, error) { once.Do(func() { heartbeat = &Heartbeat{ @@ -101,7 +101,7 @@ func GetHeartbeat(cfg *HeartbeatConfig) (*Heartbeat, error) { cfg: cfg, schema: strings.ToUpper(filter.DMHeartbeatSchema), table: strings.ToUpper(filter.DMHeartbeatTable), - secondaryTs: make(map[string]float64), + secondaryTS: make(map[string]float64), logger: log.With(zap.String("component", "heartbeat")), } }) @@ -111,13 +111,13 @@ func GetHeartbeat(cfg *HeartbeatConfig) (*Heartbeat, error) { return heartbeat, nil } -// AddTask adds a new task +// AddTask adds a new task. func (h *Heartbeat) AddTask(name string) error { h.lock <- struct{}{} // send to chan, acquire the lock defer func() { <-h.lock // read from the chan, release the lock }() - if _, ok := h.secondaryTs[name]; ok { + if _, ok := h.secondaryTS[name]; ok { return terror.ErrSyncerUnitHeartbeatRecordExists.Generate(name) } if h.primary == nil { @@ -157,22 +157,22 @@ func (h *Heartbeat) AddTask(name string) error { h.run(ctx) }() } - h.secondaryTs[name] = 0 // init to 0 + h.secondaryTS[name] = 0 // init to 0 return nil } -// RemoveTask removes a previous added task +// RemoveTask removes a previous added task. func (h *Heartbeat) RemoveTask(name string) error { h.lock <- struct{}{} defer func() { <-h.lock }() - if _, ok := h.secondaryTs[name]; !ok { + if _, ok := h.secondaryTS[name]; !ok { return terror.ErrSyncerUnitHeartbeatRecordNotFound.Generate(name) } - delete(h.secondaryTs, name) + delete(h.secondaryTS, name) - if len(h.secondaryTs) == 0 { + if len(h.secondaryTS) == 0 { // cancel work h.cancel() h.cancel = nil @@ -186,8 +186,8 @@ func (h *Heartbeat) RemoveTask(name string) error { return nil } -// TryUpdateTaskTs tries to update task's ts -func (h *Heartbeat) TryUpdateTaskTs(taskName, schema, table string, data [][]interface{}) { +// TryUpdateTaskTS tries to update task's ts. +func (h *Heartbeat) TryUpdateTaskTS(taskName, schema, table string, data [][]interface{}) { if strings.ToUpper(schema) != h.schema || strings.ToUpper(table) != h.table { h.logger.Debug("don't need to handle non-heartbeat table", zap.String("schema", schema), zap.String("table", table)) return // not heartbeat table @@ -222,8 +222,8 @@ func (h *Heartbeat) TryUpdateTaskTs(taskName, schema, table string, data [][]int select { case h.lock <- struct{}{}: - if _, ok := h.secondaryTs[taskName]; ok { - h.secondaryTs[taskName] = h.timeToSeconds(t) + if _, ok := h.secondaryTS[taskName]; ok { + h.secondaryTS[taskName] = h.timeToSeconds(t) } <-h.lock default: @@ -248,7 +248,6 @@ func (h *Heartbeat) init() error { // run create `heartbeat` table if not exists, and initialize heartbeat record, // and then update `ts` every `updateInterval` second. func (h *Heartbeat) run(ctx context.Context) { - updateTicker := time.NewTicker(time.Second * time.Duration(h.cfg.updateInterval)) defer updateTicker.Stop() @@ -276,7 +275,7 @@ func (h *Heartbeat) run(ctx context.Context) { } } -// createTable creates heartbeat database if not exists in primary +// createTable creates heartbeat database if not exists in primary. func (h *Heartbeat) createDatabase() error { createDatabase := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", h.schema) _, err := h.primary.DB.Exec(createDatabase) @@ -284,7 +283,7 @@ func (h *Heartbeat) createDatabase() error { return terror.WithScope(terror.DBErrorAdapt(err, terror.ErrDBDriverError), terror.ScopeUpstream) } -// createTable creates heartbeat table if not exists in primary +// createTable creates heartbeat table if not exists in primary. func (h *Heartbeat) createTable() error { tableName := fmt.Sprintf("`%s`.`%s`", h.schema, h.table) createTableStmt := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s ( @@ -298,7 +297,7 @@ func (h *Heartbeat) createTable() error { return terror.WithScope(terror.DBErrorAdapt(err, terror.ErrDBDriverError), terror.ScopeUpstream) } -// updateTS use `REPLACE` statement to insert or update ts +// updateTS use `REPLACE` statement to insert or update ts. func (h *Heartbeat) updateTS() error { query := fmt.Sprintf("REPLACE INTO `%s`.`%s` (`ts`, `server_id`) VALUES(UTC_TIMESTAMP(6), ?)", h.schema, h.table) _, err := h.primary.DB.Exec(query, h.cfg.serverID) @@ -314,7 +313,7 @@ func (h *Heartbeat) calculateLag(ctx context.Context) error { select { case h.lock <- struct{}{}: - for taskName, ts := range h.secondaryTs { + for taskName, ts := range h.secondaryTS { if ts == 0 { continue // do not update metrics if no valid secondary TS exists. } @@ -330,7 +329,7 @@ func (h *Heartbeat) calculateLag(ctx context.Context) error { } func reportLag(taskName string, lag float64) { - replicationLagGauge.WithLabelValues(taskName).Set(float64(lag)) + replicationLagGauge.WithLabelValues(taskName).Set(lag) } func (h *Heartbeat) getPrimaryTS() (float64, error) { @@ -363,6 +362,6 @@ func (h *Heartbeat) tsToSeconds(ts string) (float64, error) { func (h *Heartbeat) timeToSeconds(t time.Time) float64 { nsec := t.UnixNano() sec := nsec / 1e9 - nsec = nsec % 1e9 + nsec %= 1e9 return float64(sec) + float64(nsec)/1e9 } diff --git a/syncer/heartbeat_test.go b/syncer/heartbeat_test.go index 1b2648b672..e6e16330ff 100644 --- a/syncer/heartbeat_test.go +++ b/syncer/heartbeat_test.go @@ -89,7 +89,7 @@ func (t *testHeartbeatSuite) TestHeartbeat(c *C) { oldlag1 := t.lag["heartbeat_test_1"] oldlag2 := t.lag["heartbeat_test_2"] - heartbeat.TryUpdateTaskTs("heartbeat_test_1", filter.DMHeartbeatSchema, filter.DMHeartbeatTable, [][]interface{}{ + heartbeat.TryUpdateTaskTS("heartbeat_test_1", filter.DMHeartbeatSchema, filter.DMHeartbeatTable, [][]interface{}{ { "2019-05-15 15:25:42", int32(123), diff --git a/syncer/job.go b/syncer/job.go index 7fc4f53b00..cb13f5a845 100644 --- a/syncer/job.go +++ b/syncer/job.go @@ -101,7 +101,6 @@ func newJob(tp opType, sourceSchema, sourceTable, targetSchema, targetTable, sql // when cfg.ShardMode == ShardOptimistic || ShardPessimistic, ddlInfo != nil, sourceTbls == nil. func newDDLJob(ddlInfo *shardingDDLInfo, ddls []string, location, startLocation, cmdLocation binlog.Location, sourceTbls map[string]map[string]struct{}, originSQL string) *job { - j := &job{ tp: ddl, ddls: ddls, @@ -153,7 +152,7 @@ func newSkipJob(location binlog.Location) *job { } } -// put queues into bucket to monitor them +// put queues into bucket to monitor them. func queueBucketName(queueID int) string { return fmt.Sprintf("q_%d", queueID%defaultBucketCount) } diff --git a/syncer/metrics.go b/syncer/metrics.go index c19ea907a3..638f1636e5 100644 --- a/syncer/metrics.go +++ b/syncer/metrics.go @@ -167,7 +167,7 @@ var ( Buckets: prometheus.ExponentialBuckets(0.000005, 2, 25), }, []string{"type", "task"}) - // should alert + // should alert. syncerExitWithErrorCounter = metricsproxy.NewCounterVec( prometheus.CounterOpts{ Namespace: "dm", @@ -176,7 +176,7 @@ var ( Help: "counter for syncer exits with error", }, []string{"task", "source_id"}) - // some problems with it + // some problems with it. replicationLagGauge = metricsproxy.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "dm", @@ -218,7 +218,7 @@ var ( }, []string{"server_id"}) ) -// RegisterMetrics registers metrics +// RegisterMetrics registers metrics. func RegisterMetrics(registry *prometheus.Registry) { registry.MustRegister(binlogReadDurationHistogram) registry.MustRegister(binlogEventSizeHistogram) @@ -246,7 +246,6 @@ func RegisterMetrics(registry *prometheus.Registry) { // InitStatusAndMetrics register prometheus metrics and listen for status port. func InitStatusAndMetrics(addr string) { - go func() { http.HandleFunc("/status", func(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") @@ -270,6 +269,7 @@ func InitStatusAndMetrics(addr string) { } }() } + func (s *Syncer) removeLabelValuesWithTaskInMetrics(task string) { binlogReadDurationHistogram.DeleteAllAboutLabels(prometheus.Labels{"task": task}) binlogEventSizeHistogram.DeleteAllAboutLabels(prometheus.Labels{"task": task}) diff --git a/syncer/online_ddl.go b/syncer/online_ddl.go index 39c1a60231..dbbcdaf2bb 100644 --- a/syncer/online_ddl.go +++ b/syncer/online_ddl.go @@ -31,15 +31,13 @@ import ( "go.uber.org/zap" ) -var ( - // OnlineDDLSchemes is scheme name => online ddl handler - OnlineDDLSchemes = map[string]func(*tcontext.Context, *config.SubTaskConfig) (OnlinePlugin, error){ - config.PT: NewPT, - config.GHOST: NewGhost, - } -) +// OnlineDDLSchemes is scheme name => online ddl handler. +var OnlineDDLSchemes = map[string]func(*tcontext.Context, *config.SubTaskConfig) (OnlinePlugin, error){ + config.PT: NewPT, + config.GHOST: NewGhost, +} -// OnlinePlugin handles online ddl solutions like pt, gh-ost +// OnlinePlugin handles online ddl solutions like pt, gh-ost. type OnlinePlugin interface { // Applys does: // * detect online ddl @@ -61,7 +59,7 @@ type OnlinePlugin interface { Close() } -// TableType is type of table +// TableType is type of table. type TableType string const ( @@ -70,7 +68,7 @@ const ( trashTable TableType = "trash table" // means we should ignore these tables ) -// GhostDDLInfo stores ghost information and ddls +// GhostDDLInfo stores ghost information and ddls. type GhostDDLInfo struct { Schema string `json:"schema"` Table string `json:"table"` @@ -78,7 +76,7 @@ type GhostDDLInfo struct { DDLs []string `json:"ddls"` } -// OnlineDDLStorage stores sharding group online ddls information +// OnlineDDLStorage stores sharding group online ddls information. type OnlineDDLStorage struct { sync.RWMutex @@ -96,7 +94,7 @@ type OnlineDDLStorage struct { logCtx *tcontext.Context } -// NewOnlineDDLStorage creates a new online ddl storager +// NewOnlineDDLStorage creates a new online ddl storager. func NewOnlineDDLStorage(logCtx *tcontext.Context, cfg *config.SubTaskConfig) *OnlineDDLStorage { s := &OnlineDDLStorage{ cfg: cfg, @@ -110,7 +108,7 @@ func NewOnlineDDLStorage(logCtx *tcontext.Context, cfg *config.SubTaskConfig) *O return s } -// Init initials online handler +// Init initials online handler. func (s *OnlineDDLStorage) Init(tctx *tcontext.Context) error { onlineDB := s.cfg.To onlineDB.RawDBCfg = config.DefaultRawDBConfig().SetReadTimeout(maxCheckPointTimeout) @@ -129,7 +127,7 @@ func (s *OnlineDDLStorage) Init(tctx *tcontext.Context) error { return s.Load(tctx) } -// Load loads information from storage +// Load loads information from storage. func (s *OnlineDDLStorage) Load(tctx *tcontext.Context) error { s.Lock() defer s.Unlock() @@ -168,7 +166,7 @@ func (s *OnlineDDLStorage) Load(tctx *tcontext.Context) error { return terror.WithScope(terror.DBErrorAdapt(rows.Err(), terror.ErrDBDriverError), terror.ScopeDownstream) } -// Get returns ddls by given schema/table +// Get returns ddls by given schema/table. func (s *OnlineDDLStorage) Get(ghostSchema, ghostTable string) *GhostDDLInfo { s.RLock() defer s.RUnlock() @@ -188,7 +186,7 @@ func (s *OnlineDDLStorage) Get(ghostSchema, ghostTable string) *GhostDDLInfo { return clone } -// Save saves online ddl information +// Save saves online ddl information. func (s *OnlineDDLStorage) Save(tctx *tcontext.Context, ghostSchema, ghostTable, realSchema, realTable, ddl string) error { s.Lock() defer s.Unlock() @@ -225,7 +223,7 @@ func (s *OnlineDDLStorage) Save(tctx *tcontext.Context, ghostSchema, ghostTable, return terror.WithScope(err, terror.ScopeDownstream) } -// Delete deletes online ddl informations +// Delete deletes online ddl informations. func (s *OnlineDDLStorage) Delete(tctx *tcontext.Context, ghostSchema, ghostTable string) error { s.Lock() defer s.Unlock() @@ -246,7 +244,7 @@ func (s *OnlineDDLStorage) Delete(tctx *tcontext.Context, ghostSchema, ghostTabl return nil } -// Clear clears online ddl information from storage +// Clear clears online ddl information from storage. func (s *OnlineDDLStorage) Clear(tctx *tcontext.Context) error { s.Lock() defer s.Unlock() @@ -262,12 +260,12 @@ func (s *OnlineDDLStorage) Clear(tctx *tcontext.Context) error { return nil } -// ResetConn implements OnlinePlugin.ResetConn +// ResetConn implements OnlinePlugin.ResetConn. func (s *OnlineDDLStorage) ResetConn(tctx *tcontext.Context) error { return s.dbConn.resetConn(tctx) } -// Close closes database connection +// Close closes database connection. func (s *OnlineDDLStorage) Close() { s.Lock() defer s.Unlock() @@ -303,5 +301,5 @@ func (s *OnlineDDLStorage) createTable(tctx *tcontext.Context) error { } func escapeSingleQuote(str string) string { - return strings.Replace(str, "'", "''", -1) + return strings.ReplaceAll(str, "'", "''") } diff --git a/syncer/optimist.go b/syncer/optimist.go index 1965d10798..2ed735dcb6 100644 --- a/syncer/optimist.go +++ b/syncer/optimist.go @@ -94,6 +94,7 @@ func (s *Syncer) handleQueryEventOptimistic( err = s.execError.Get() if err != nil { ec.tctx.L().Error("error detected when executing SQL job", log.ShortError(err)) + // nolint:nilerr return nil } @@ -214,6 +215,7 @@ func (s *Syncer) handleQueryEventOptimistic( err = s.execError.Get() if err != nil { s.tctx.L().Error("error detected when executing SQL job", log.ShortError(err)) + // nolint:nilerr return nil } diff --git a/syncer/pt_osc.go b/syncer/pt_osc.go index a9beda71d9..17a8310f6f 100644 --- a/syncer/pt_osc.go +++ b/syncer/pt_osc.go @@ -29,12 +29,12 @@ import ( // PT handles pt online schema changes // (_*).*_new ghost table // (_*).*_old ghost trash table -// we don't support `--new-table-name` flag +// we don't support `--new-table-name` flag. type PT struct { storge *OnlineDDLStorage } -// NewPT returns pt online schema changes plugin +// NewPT returns pt online schema changes plugin. func NewPT(tctx *tcontext.Context, cfg *config.SubTaskConfig) (OnlinePlugin, error) { g := &PT{ storge: NewOnlineDDLStorage(tcontext.Background().WithLogger(tctx.L().WithFields(zap.String("online ddl", "pt-ost"))), cfg), // create a context for logger @@ -44,7 +44,8 @@ func NewPT(tctx *tcontext.Context, cfg *config.SubTaskConfig) (OnlinePlugin, err } // Apply implements interface. -// returns ddls, real schema, real table, error +// returns ddls, real schema, real table, error. +// nolint:dupl func (p *PT) Apply(tctx *tcontext.Context, tables []*filter.Table, statement string, stmt ast.StmtNode) ([]string, string, string, error) { if len(tables) < 1 { return nil, "", "", terror.ErrSyncerUnitPTApplyEmptyTable.Generate() @@ -56,8 +57,7 @@ func (p *PT) Apply(tctx *tcontext.Context, tables []*filter.Table, statement str switch tp { case realTable: - switch stmt.(type) { - case *ast.RenameTableStmt: + if _, ok := stmt.(*ast.RenameTableStmt); ok { if len(tables) != parserpkg.SingleRenameTableNameNum { return nil, "", "", terror.ErrSyncerUnitPTRenameTableNotValid.Generate() } @@ -72,8 +72,7 @@ func (p *PT) Apply(tctx *tcontext.Context, tables []*filter.Table, statement str return []string{statement}, schema, table, nil case trashTable: // ignore trashTable - switch stmt.(type) { - case *ast.RenameTableStmt: + if _, ok := stmt.(*ast.RenameTableStmt); ok { if len(tables) != parserpkg.SingleRenameTableNameNum { return nil, "", "", terror.ErrSyncerUnitPTRenameTableNotValid.Generate() } @@ -129,7 +128,7 @@ func (p *PT) Apply(tctx *tcontext.Context, tables []*filter.Table, statement str return nil, schema, table, nil } -// Finish implements interface +// Finish implements interface. func (p *PT) Finish(tcxt *tcontext.Context, schema, table string) error { if p == nil { return nil @@ -138,7 +137,7 @@ func (p *PT) Finish(tcxt *tcontext.Context, schema, table string) error { return p.storge.Delete(tcxt, schema, table) } -// TableType implements interface +// TableType implements interface. func (p *PT) TableType(table string) TableType { // 5 is _ _old/new if len(table) > 5 { @@ -154,7 +153,7 @@ func (p *PT) TableType(table string) TableType { return realTable } -// RealName implements interface +// RealName implements interface. func (p *PT) RealName(schema, table string) (string, string) { tp := p.TableType(table) if tp == trashTable || tp == ghostTable { @@ -165,17 +164,17 @@ func (p *PT) RealName(schema, table string) (string, string) { return schema, table } -// Clear clears online ddl information +// Clear clears online ddl information. func (p *PT) Clear(tctx *tcontext.Context) error { return p.storge.Clear(tctx) } -// Close implements interface +// Close implements interface. func (p *PT) Close() { p.storge.Close() } -// ResetConn implements interface +// ResetConn implements interface. func (p *PT) ResetConn(tctx *tcontext.Context) error { return p.storge.ResetConn(tctx) } diff --git a/syncer/relay.go b/syncer/relay.go index 6cd5a82d9a..0997a78e7b 100644 --- a/syncer/relay.go +++ b/syncer/relay.go @@ -49,17 +49,18 @@ func (s *Syncer) setInitActiveRelayLog(ctx context.Context) error { } checkLocation := s.checkpoint.GlobalPoint() - if binlog.ComparePosition(checkLocation.Position, binlog.MinPosition) > 0 { + switch { + case binlog.ComparePosition(checkLocation.Position, binlog.MinPosition) > 0: // continue from previous checkpoint pos = checkLocation.Position extractPos = true - } else if s.cfg.Mode == config.ModeIncrement { + case s.cfg.Mode == config.ModeIncrement: // fresh start for task-mode increment pos = mysql.Position{ Name: s.cfg.Meta.BinLogName, Pos: s.cfg.Meta.BinLogPos, } - } else { + default: // start from dumper or loader, get current pos from master pos, _, err = s.fromDB.getMasterStatus(ctx, s.cfg.Flavor) if err != nil { diff --git a/syncer/safe-mode/mode.go b/syncer/safe-mode/mode.go index af94a21fc9..a482e5562f 100644 --- a/syncer/safe-mode/mode.go +++ b/syncer/safe-mode/mode.go @@ -24,21 +24,21 @@ import ( ) // SafeMode controls whether enable safe-mode through a mechanism similar to reference-count -// indicates enabled excepting the count is 0 +// indicates enabled excepting the count is 0. type SafeMode struct { mu sync.RWMutex count int32 tables map[string]struct{} } -// NewSafeMode creates a new SafeMode instance +// NewSafeMode creates a new SafeMode instance. func NewSafeMode() *SafeMode { return &SafeMode{ tables: make(map[string]struct{}), } } -// Add adds n to the count, n can be negative +// Add adds n to the count, n can be negative. func (m *SafeMode) Add(tctx *tcontext.Context, n int32) error { m.mu.Lock() defer m.mu.Unlock() @@ -46,7 +46,7 @@ func (m *SafeMode) Add(tctx *tcontext.Context, n int32) error { } // IncrForTable tries to add 1 on the count if the table not added before -// can only be desc with DescForTable +// can only be desc with DescForTable. func (m *SafeMode) IncrForTable(tctx *tcontext.Context, schema, table string) error { key := key(schema, table) @@ -59,7 +59,7 @@ func (m *SafeMode) IncrForTable(tctx *tcontext.Context, schema, table string) er return nil } -// DescForTable tries to add -1 on the count if the table added before +// DescForTable tries to add -1 on the count if the table added before. func (m *SafeMode) DescForTable(tctx *tcontext.Context, schema, table string) error { key := key(schema, table) @@ -72,7 +72,7 @@ func (m *SafeMode) DescForTable(tctx *tcontext.Context, schema, table string) er return nil } -// Reset resets to the state of not-enable +// Reset resets to the state of not-enable. func (m *SafeMode) Reset(tctx *tcontext.Context) { m.mu.Lock() defer m.mu.Unlock() @@ -82,14 +82,14 @@ func (m *SafeMode) Reset(tctx *tcontext.Context) { m.tables = make(map[string]struct{}) } -// Enable returns whether is enabled currently +// Enable returns whether is enabled currently. func (m *SafeMode) Enable() bool { m.mu.RLock() defer m.mu.RUnlock() return m.count != 0 } -// setCount sets the count, called internal +// setCount sets the count, called internal. func (m *SafeMode) setCount(tctx *tcontext.Context, n int32) error { if n < 0 { return terror.ErrSyncUnitSafeModeSetCount.Generatef("set negative count (%d) for safe-mode not valid", m.count) diff --git a/syncer/safe-mode/mode_test.go b/syncer/safe-mode/mode_test.go index b73a94afc3..f4ab5c844b 100644 --- a/syncer/safe-mode/mode_test.go +++ b/syncer/safe-mode/mode_test.go @@ -27,8 +27,7 @@ func TestSuite(t *testing.T) { TestingT(t) } -type testModeSuite struct { -} +type testModeSuite struct{} func (t *testModeSuite) TestMode(c *C) { m := NewSafeMode() diff --git a/syncer/shardddl/optimist.go b/syncer/shardddl/optimist.go index 9a8bba0f39..073176b317 100644 --- a/syncer/shardddl/optimist.go +++ b/syncer/shardddl/optimist.go @@ -81,8 +81,8 @@ func (o *Optimist) Reset() { // ConstructInfo constructs a shard DDL info. func (o *Optimist) ConstructInfo(upSchema, upTable, downSchema, downTable string, - DDLs []string, tiBefore *model.TableInfo, tisAfter []*model.TableInfo) optimism.Info { - return optimism.NewInfo(o.task, o.source, upSchema, upTable, downSchema, downTable, DDLs, tiBefore, tisAfter) + ddls []string, tiBefore *model.TableInfo, tisAfter []*model.TableInfo) optimism.Info { + return optimism.NewInfo(o.task, o.source, upSchema, upTable, downSchema, downTable, ddls, tiBefore, tisAfter) } // PutInfo puts the shard DDL info into etcd and returns the revision. diff --git a/syncer/shardddl/optimist_test.go b/syncer/shardddl/optimist_test.go index 213912e0a0..8e3c9bc24c 100644 --- a/syncer/shardddl/optimist_test.go +++ b/syncer/shardddl/optimist_test.go @@ -30,8 +30,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -type testOptimist struct { -} +type testOptimist struct{} var _ = Suite(&testOptimist{}) @@ -76,7 +75,7 @@ func (t *testOptimist) TestOptimist(c *C) { p = parser.New() se = mock.NewContext() - tblID int64 = 111 + tblID int64 = 222 DDLs1 = []string{"ALTER TABLE bar ADD COLUMN c1 TEXT"} DDLs2 = []string{"ALTER TABLE bar ADD COLUMN c1 DATETIME"} tiBefore = createTableInfo(c, p, se, tblID, `CREATE TABLE bar (id INT PRIMARY KEY)`) diff --git a/syncer/shardddl/pessimist.go b/syncer/shardddl/pessimist.go index 256fd2919c..524c8aee24 100644 --- a/syncer/shardddl/pessimist.go +++ b/syncer/shardddl/pessimist.go @@ -60,8 +60,8 @@ func (p *Pessimist) Reset() { } // ConstructInfo constructs a shard DDL info. -func (p *Pessimist) ConstructInfo(schema, table string, DDLs []string) pessimism.Info { - return pessimism.NewInfo(p.task, p.source, schema, table, DDLs) +func (p *Pessimist) ConstructInfo(schema, table string, ddls []string) pessimism.Info { + return pessimism.NewInfo(p.task, p.source, schema, table, ddls) } // PutInfo puts the shard DDL info into etcd and returns the revision. diff --git a/syncer/shardddl/pessimist_test.go b/syncer/shardddl/pessimist_test.go index 020b491629..6b01e8da8e 100644 --- a/syncer/shardddl/pessimist_test.go +++ b/syncer/shardddl/pessimist_test.go @@ -28,9 +28,7 @@ import ( "github.com/pingcap/dm/pkg/terror" ) -var ( - etcdTestCli *clientv3.Client -) +var etcdTestCli *clientv3.Client type testPessimist struct{} diff --git a/syncer/sharding-meta/shardmeta.go b/syncer/sharding-meta/shardmeta.go index dc9d143228..1a4af407bf 100644 --- a/syncer/sharding-meta/shardmeta.go +++ b/syncer/sharding-meta/shardmeta.go @@ -28,7 +28,7 @@ import ( "github.com/pingcap/dm/pkg/utils" ) -// DDLItem records ddl information used in sharding sequence organization +// DDLItem records ddl information used in sharding sequence organization. type DDLItem struct { FirstLocation binlog.Location `json:"-"` // first DDL's binlog Pos, not the End_log_pos of the event DDLs []string `json:"ddls"` // DDLs, these ddls are in the same QueryEvent @@ -40,7 +40,7 @@ type DDLItem struct { FirstGTIDSet string `json:"first-gtid-set"` } -// NewDDLItem creates a new DDLItem +// NewDDLItem creates a new DDLItem. func NewDDLItem(location binlog.Location, ddls []string, source string) *DDLItem { gsetStr := "" if location.GetGTID() != nil { @@ -57,12 +57,12 @@ func NewDDLItem(location binlog.Location, ddls []string, source string) *DDLItem } } -// String returns the item's format string value +// String returns the item's format string value. func (item *DDLItem) String() string { return fmt.Sprintf("first-location: %s ddls: %+v source: %s", item.FirstLocation, item.DDLs, item.Source) } -// ShardingSequence records a list of DDLItem +// ShardingSequence records a list of DDLItem. type ShardingSequence struct { Items []*DDLItem `json:"items"` } @@ -80,7 +80,7 @@ func (seq *ShardingSequence) IsPrefixSequence(other *ShardingSequence) bool { return true } -// String returns the ShardingSequence's json string +// String returns the ShardingSequence's json string. func (seq *ShardingSequence) String() string { jsonSeq, err := json.Marshal(seq.Items) if err != nil { @@ -91,7 +91,7 @@ func (seq *ShardingSequence) String() string { // ShardingMeta stores sharding ddl sequence // including global sequence and each source's own sequence -// NOTE: sharding meta is not thread safe, it must be used in thread safe context +// NOTE: sharding meta is not thread safe, it must be used in thread safe context. type ShardingMeta struct { activeIdx int // the first unsynced DDL index global *ShardingSequence // merged sharding sequence of all source tables @@ -101,7 +101,7 @@ type ShardingMeta struct { enableGTID bool // whether enableGTID, used to compare location } -// NewShardingMeta creates a new ShardingMeta +// NewShardingMeta creates a new ShardingMeta. func NewShardingMeta(schema, table string, enableGTID bool) *ShardingMeta { return &ShardingMeta{ tableName: dbutil.TableName(schema, table), @@ -112,7 +112,7 @@ func NewShardingMeta(schema, table string, enableGTID bool) *ShardingMeta { } } -// RestoreFromData restores ShardingMeta from given data +// RestoreFromData restores ShardingMeta from given data. func (meta *ShardingMeta) RestoreFromData(sourceTableID string, activeIdx int, isGlobal bool, data []byte, flavor string) error { items := make([]*DDLItem, 0) err := json.Unmarshal(data, &items) @@ -141,12 +141,12 @@ func (meta *ShardingMeta) RestoreFromData(sourceTableID string, activeIdx int, i return nil } -// ActiveIdx returns the activeIdx of sharding meta +// ActiveIdx returns the activeIdx of sharding meta. func (meta *ShardingMeta) ActiveIdx() int { return meta.activeIdx } -// Reinitialize reinitialize the shardingmeta +// Reinitialize reinitialize the shardingmeta. func (meta *ShardingMeta) Reinitialize() { meta.activeIdx = 0 meta.global = &ShardingSequence{make([]*DDLItem, 0)} @@ -207,7 +207,7 @@ func (meta *ShardingMeta) AddItem(item *DDLItem) (active bool, err error) { return index == meta.activeIdx, nil } -// GetGlobalActiveDDL returns activeDDL in global sequence +// GetGlobalActiveDDL returns activeDDL in global sequence. func (meta *ShardingMeta) GetGlobalActiveDDL() *DDLItem { if meta.activeIdx < len(meta.global.Items) { return meta.global.Items[meta.activeIdx] @@ -215,14 +215,14 @@ func (meta *ShardingMeta) GetGlobalActiveDDL() *DDLItem { return nil } -// GetGlobalItems returns global DDLItems +// GetGlobalItems returns global DDLItems. func (meta *ShardingMeta) GetGlobalItems() []*DDLItem { return meta.global.Items } // GetActiveDDLItem returns the source table's active DDLItem // if in DDL unsynced procedure, the active DDLItem means the syncing DDL -// if in re-sync procedure, the active DDLItem means the next syncing DDL in DDL syncing sequence, may be nil +// if in re-sync procedure, the active DDLItem means the next syncing DDL in DDL syncing sequence, may be nil. func (meta *ShardingMeta) GetActiveDDLItem(tableSource string) *DDLItem { source, ok := meta.sources[tableSource] if !ok { @@ -234,7 +234,7 @@ func (meta *ShardingMeta) GetActiveDDLItem(tableSource string) *DDLItem { return nil } -// InSequenceSharding returns whether in sequence sharding +// InSequenceSharding returns whether in sequence sharding. func (meta *ShardingMeta) InSequenceSharding() bool { globalItemCount := len(meta.global.Items) return globalItemCount > 0 && meta.activeIdx < globalItemCount @@ -253,7 +253,7 @@ func (meta *ShardingMeta) ResolveShardingDDL() bool { return false } -// ActiveDDLFirstLocation returns the first binlog position of active DDL +// ActiveDDLFirstLocation returns the first binlog position of active DDL. func (meta *ShardingMeta) ActiveDDLFirstLocation() (binlog.Location, error) { if meta.activeIdx >= len(meta.global.Items) { return binlog.Location{}, terror.ErrSyncUnitDDLActiveIndexLarger.Generate(meta.activeIdx, meta.global.Items) @@ -262,7 +262,7 @@ func (meta *ShardingMeta) ActiveDDLFirstLocation() (binlog.Location, error) { return meta.global.Items[meta.activeIdx].FirstLocation, nil } -// FlushData returns sharding meta flush SQL and args +// FlushData returns sharding meta flush SQL and args. func (meta *ShardingMeta) FlushData(sourceID, tableID string) ([]string, [][]interface{}) { if len(meta.global.Items) == 0 { sql2 := fmt.Sprintf("DELETE FROM %s where source_id=? and target_table_id=?", meta.tableName) diff --git a/syncer/sharding-meta/shardmeta_test.go b/syncer/sharding-meta/shardmeta_test.go index 6b0b199940..d06c9b06e1 100644 --- a/syncer/sharding-meta/shardmeta_test.go +++ b/syncer/sharding-meta/shardmeta_test.go @@ -29,8 +29,7 @@ func TestSuite(t *testing.T) { check.TestingT(t) } -type testShardMetaSuite struct { -} +type testShardMetaSuite struct{} func (t *testShardMetaSuite) TestShardingMeta(c *check.C) { var ( @@ -181,7 +180,7 @@ func (t *testShardMetaSuite) TestShardingMeta(c *check.C) { c.Assert(meta.GetActiveDDLItem(table2), check.IsNil) c.Assert(meta.GetActiveDDLItem(table3), check.IsNil) c.Assert(meta.InSequenceSharding(), check.IsFalse) - location, err = meta.ActiveDDLFirstLocation() + _, err = meta.ActiveDDLFirstLocation() c.Assert(err, check.ErrorMatches, fmt.Sprintf("\\[.*\\], Message: activeIdx %d larger than length of global DDLItems: .*", meta.ActiveIdx())) sqls, args = meta.FlushData(sourceID, tableID) diff --git a/syncer/sharding_group.go b/syncer/sharding_group.go index 838df983d5..3626c6e1aa 100644 --- a/syncer/sharding_group.go +++ b/syncer/sharding_group.go @@ -88,7 +88,7 @@ import ( "go.uber.org/zap" ) -// ShardingGroup represents a sharding DDL sync group +// ShardingGroup represents a sharding DDL sync group. type ShardingGroup struct { sync.RWMutex // remain count waiting for syncing @@ -111,7 +111,7 @@ type ShardingGroup struct { enableGTID bool } -// NewShardingGroup creates a new ShardingGroup +// NewShardingGroup creates a new ShardingGroup. func NewShardingGroup(sourceID, shardMetaSchema, shardMetaTable string, sources []string, meta *shardmeta.ShardingMeta, isSchemaOnly bool, flavor string, enableGTID bool) *ShardingGroup { sg := &ShardingGroup{ remain: len(sources), @@ -185,7 +185,7 @@ func (sg *ShardingGroup) Leave(sources []string) error { } // Reset resets all sources to un-synced state -// when the previous sharding DDL synced and resolved, we need reset it +// when the previous sharding DDL synced and resolved, we need reset it. func (sg *ShardingGroup) Reset() { sg.Lock() defer sg.Unlock() @@ -239,7 +239,7 @@ func (sg *ShardingGroup) CheckSyncing(source string, location binlog.Location) ( return binlog.CompareLocation(activeDDLItem.FirstLocation, location, sg.enableGTID) > 0 } -// UnresolvedGroupInfo returns pb.ShardingGroup if is unresolved, else returns nil +// UnresolvedGroupInfo returns pb.ShardingGroup if is unresolved, else returns nil. func (sg *ShardingGroup) UnresolvedGroupInfo() *pb.ShardingGroup { sg.RLock() defer sg.RUnlock() @@ -264,7 +264,7 @@ func (sg *ShardingGroup) UnresolvedGroupInfo() *pb.ShardingGroup { return group } -// Sources returns all sources (and whether synced) +// Sources returns all sources (and whether synced). func (sg *ShardingGroup) Sources() map[string]bool { sg.RLock() defer sg.RUnlock() @@ -275,7 +275,7 @@ func (sg *ShardingGroup) Sources() map[string]bool { return ret } -// Tables returns all source tables' pair +// Tables returns all source tables' pair. func (sg *ShardingGroup) Tables() [][]string { sources := sg.Sources() tables := make([][]string, 0, len(sources)) @@ -286,7 +286,7 @@ func (sg *ShardingGroup) Tables() [][]string { return tables } -// UnresolvedTables returns all source tables' pair if is unresolved, else returns nil +// UnresolvedTables returns all source tables' pair if is unresolved, else returns nil. func (sg *ShardingGroup) UnresolvedTables() [][]string { sg.RLock() defer sg.RUnlock() @@ -305,7 +305,7 @@ func (sg *ShardingGroup) UnresolvedTables() [][]string { return tables } -// FirstLocationUnresolved returns the first DDL pos if un-resolved, else nil +// FirstLocationUnresolved returns the first DDL pos if un-resolved, else nil. func (sg *ShardingGroup) FirstLocationUnresolved() *binlog.Location { sg.RLock() defer sg.RUnlock() @@ -323,7 +323,7 @@ func (sg *ShardingGroup) FirstLocationUnresolved() *binlog.Location { return nil } -// FirstEndPosUnresolved returns the first DDL End_log_pos if un-resolved, else nil +// FirstEndPosUnresolved returns the first DDL End_log_pos if un-resolved, else nil. func (sg *ShardingGroup) FirstEndPosUnresolved() *binlog.Location { sg.RLock() defer sg.RUnlock() @@ -335,12 +335,12 @@ func (sg *ShardingGroup) FirstEndPosUnresolved() *binlog.Location { return nil } -// String implements Stringer.String +// String implements Stringer.String. func (sg *ShardingGroup) String() string { return fmt.Sprintf("IsSchemaOnly:%v remain:%d, sources:%+v", sg.IsSchemaOnly, sg.remain, sg.sources) } -// ResolveShardingDDL resolves sharding DDL in sharding group +// ResolveShardingDDL resolves sharding DDL in sharding group. func (sg *ShardingGroup) ResolveShardingDDL() bool { sg.Lock() defer sg.Unlock() @@ -349,7 +349,7 @@ func (sg *ShardingGroup) ResolveShardingDDL() bool { return reset } -// ActiveDDLFirstLocation returns the first binlog position of active DDL +// ActiveDDLFirstLocation returns the first binlog position of active DDL. func (sg *ShardingGroup) ActiveDDLFirstLocation() (binlog.Location, error) { sg.RLock() defer sg.RUnlock() @@ -357,22 +357,22 @@ func (sg *ShardingGroup) ActiveDDLFirstLocation() (binlog.Location, error) { return location, err } -// FlushData returns sharding meta flush SQLs and args +// FlushData returns sharding meta flush SQLs and args. func (sg *ShardingGroup) FlushData(targetTableID string) ([]string, [][]interface{}) { sg.RLock() defer sg.RUnlock() return sg.meta.FlushData(sg.sourceID, targetTableID) } -// GenTableID generates table ID -func GenTableID(schema, table string) (ID string, isSchemaOnly bool) { +// GenTableID generates table ID. +func GenTableID(schema, table string) (id string, isSchemaOnly bool) { if len(table) == 0 { return fmt.Sprintf("`%s`", schema), true } return fmt.Sprintf("`%s`.`%s`", schema, table), false } -// UnpackTableID unpacks table ID to pair +// UnpackTableID unpacks table ID to pair. func UnpackTableID(id string) (string, string) { parts := strings.Split(id, "`.`") schema := strings.TrimLeft(parts[0], "`") @@ -380,7 +380,7 @@ func UnpackTableID(id string) (string, string) { return schema, table } -// ShardingGroupKeeper used to keep ShardingGroup +// ShardingGroupKeeper used to keep ShardingGroup. type ShardingGroupKeeper struct { sync.RWMutex groups map[string]*ShardingGroup // target table ID -> ShardingGroup @@ -396,7 +396,7 @@ type ShardingGroupKeeper struct { tctx *tcontext.Context } -// NewShardingGroupKeeper creates a new ShardingGroupKeeper +// NewShardingGroupKeeper creates a new ShardingGroupKeeper. func NewShardingGroupKeeper(tctx *tcontext.Context, cfg *config.SubTaskConfig) *ShardingGroupKeeper { k := &ShardingGroupKeeper{ groups: make(map[string]*ShardingGroup), @@ -409,7 +409,7 @@ func NewShardingGroupKeeper(tctx *tcontext.Context, cfg *config.SubTaskConfig) * return k } -// AddGroup adds new group(s) according to target schema, table and source IDs +// AddGroup adds new group(s) according to target schema, table and source IDs. func (k *ShardingGroupKeeper) AddGroup(targetSchema, targetTable string, sourceIDs []string, meta *shardmeta.ShardingMeta, merge bool) (needShardingHandle bool, group *ShardingGroup, synced bool, remain int, err error) { // if need to support target table-level sharding DDL // we also need to support target schema-level sharding DDL @@ -428,20 +428,21 @@ func (k *ShardingGroupKeeper) AddGroup(targetSchema, targetTable string, sourceI } } - var ok bool - if group, ok = k.groups[targetTableID]; !ok { + group, ok := k.groups[targetTableID] + switch { + case !ok: group = NewShardingGroup(k.cfg.SourceID, k.shardMetaSchema, k.shardMetaTable, sourceIDs, meta, false, k.cfg.Flavor, k.cfg.EnableGTID) k.groups[targetTableID] = group - } else if merge { + case merge: needShardingHandle, synced, remain, err = k.groups[targetTableID].Merge(sourceIDs) - } else { + default: err = terror.ErrSyncUnitDupTableGroup.Generate(targetTableID) } return } -// Init does initialization staff +// Init does initialization staff. func (k *ShardingGroupKeeper) Init() error { k.clear() sgkDB := k.cfg.To @@ -455,14 +456,14 @@ func (k *ShardingGroupKeeper) Init() error { return k.prepare() } -// clear clears all sharding groups +// clear clears all sharding groups. func (k *ShardingGroupKeeper) clear() { k.Lock() defer k.Unlock() k.groups = make(map[string]*ShardingGroup) } -// ResetGroups resets group's sync status +// ResetGroups resets group's sync status. func (k *ShardingGroupKeeper) ResetGroups() { k.RLock() defer k.RUnlock() @@ -475,7 +476,7 @@ func (k *ShardingGroupKeeper) ResetGroups() { } // LeaveGroup leaves group according to target schema, table and source IDs -// LeaveGroup doesn't affect in syncing process +// LeaveGroup doesn't affect in syncing process. func (k *ShardingGroupKeeper) LeaveGroup(targetSchema, targetTable string, sources []string) error { schemaID, _ := GenTableID(targetSchema, "") targetTableID, _ := GenTableID(targetSchema, targetTable) @@ -510,7 +511,6 @@ func (k *ShardingGroupKeeper) LeaveGroup(targetSchema, targetTable string, sourc func (k *ShardingGroupKeeper) TrySync( targetSchema, targetTable, source string, location, endLocation binlog.Location, ddls []string) ( needShardingHandle bool, group *ShardingGroup, synced, active bool, remain int, err error) { - targetTableID, schemaOnly := GenTableID(targetSchema, targetTable) if schemaOnly { // NOTE: now we don't support syncing for schema only sharding DDL @@ -528,7 +528,7 @@ func (k *ShardingGroupKeeper) TrySync( return true, group, synced, active, remain, err } -// InSyncing checks whether the source is in sharding syncing, that is to say not before active DDL +// InSyncing checks whether the source is in sharding syncing, that is to say not before active DDL. func (k *ShardingGroupKeeper) InSyncing(targetSchema, targetTable, source string, location binlog.Location) bool { group := k.Group(targetSchema, targetTable) if group == nil { @@ -542,7 +542,7 @@ func (k *ShardingGroupKeeper) InSyncing(targetSchema, targetTable, source string // all source tables which with DDLs are un-resolved // NOTE: this func only ensure the returned tables are current un-resolved // if passing the returned tables to other func (like checkpoint), -// must ensure their sync state not changed in this progress +// must ensure their sync state not changed in this progress. func (k *ShardingGroupKeeper) UnresolvedTables() (map[string]bool, [][]string) { ids := make(map[string]bool) tables := make([][]string, 0, 10) @@ -559,7 +559,7 @@ func (k *ShardingGroupKeeper) UnresolvedTables() (map[string]bool, [][]string) { return ids, tables } -// Group returns target table's group, nil if not exist +// Group returns target table's group, nil if not exist. func (k *ShardingGroupKeeper) Group(targetSchema, targetTable string) *ShardingGroup { targetTableID, _ := GenTableID(targetSchema, targetTable) k.RLock() @@ -567,7 +567,7 @@ func (k *ShardingGroupKeeper) Group(targetSchema, targetTable string) *ShardingG return k.groups[targetTableID] } -// lowestFirstLocationInGroups returns the lowest pos in all groups which are unresolved +// lowestFirstLocationInGroups returns the lowest pos in all groups which are unresolved. func (k *ShardingGroupKeeper) lowestFirstLocationInGroups() *binlog.Location { k.RLock() defer k.RUnlock() @@ -586,7 +586,7 @@ func (k *ShardingGroupKeeper) lowestFirstLocationInGroups() *binlog.Location { return lowest } -// AdjustGlobalLocation adjusts globalLocation with sharding groups' lowest first point +// AdjustGlobalLocation adjusts globalLocation with sharding groups' lowest first point. func (k *ShardingGroupKeeper) AdjustGlobalLocation(globalLocation binlog.Location) binlog.Location { lowestFirstLocation := k.lowestFirstLocationInGroups() if lowestFirstLocation != nil && binlog.CompareLocation(*lowestFirstLocation, globalLocation, k.cfg.EnableGTID) < 0 { @@ -625,7 +625,7 @@ func (k *ShardingGroupKeeper) UnresolvedGroups() []*pb.ShardingGroup { return groups } -// ResolveShardingDDL resolves one sharding DDL in specific group +// ResolveShardingDDL resolves one sharding DDL in specific group. func (k *ShardingGroupKeeper) ResolveShardingDDL(targetSchema, targetTable string) (bool, error) { group := k.Group(targetSchema, targetTable) if group != nil { @@ -634,7 +634,7 @@ func (k *ShardingGroupKeeper) ResolveShardingDDL(targetSchema, targetTable strin return false, terror.ErrSyncUnitShardingGroupNotFound.Generate(targetSchema, targetTable) } -// ActiveDDLFirstLocation returns the binlog position of active DDL +// ActiveDDLFirstLocation returns the binlog position of active DDL. func (k *ShardingGroupKeeper) ActiveDDLFirstLocation(targetSchema, targetTable string) (binlog.Location, error) { group := k.Group(targetSchema, targetTable) k.Lock() @@ -646,7 +646,7 @@ func (k *ShardingGroupKeeper) ActiveDDLFirstLocation(targetSchema, targetTable s return binlog.Location{}, terror.ErrSyncUnitShardingGroupNotFound.Generate(targetSchema, targetTable) } -// PrepareFlushSQLs returns all sharding meta flushed SQLs except for given table IDs +// PrepareFlushSQLs returns all sharding meta flushed SQLs except for given table IDs. func (k *ShardingGroupKeeper) PrepareFlushSQLs(exceptTableIDs map[string]bool) ([]string, [][]interface{}) { k.RLock() defer k.RUnlock() @@ -669,7 +669,7 @@ func (k *ShardingGroupKeeper) PrepareFlushSQLs(exceptTableIDs map[string]bool) ( return sqls, args } -// Prepare inits sharding meta schema and tables if not exists +// Prepare inits sharding meta schema and tables if not exists. func (k *ShardingGroupKeeper) prepare() error { if err := k.createSchema(); err != nil { return err @@ -678,7 +678,7 @@ func (k *ShardingGroupKeeper) prepare() error { return k.createTable() } -// Close closes sharding group keeper +// Close closes sharding group keeper. func (k *ShardingGroupKeeper) Close() { closeBaseDB(k.tctx, k.db) } @@ -707,7 +707,7 @@ func (k *ShardingGroupKeeper) createTable() error { return terror.WithScope(err, terror.ScopeDownstream) } -// LoadShardMeta implements CheckPoint.LoadShardMeta +// LoadShardMeta implements CheckPoint.LoadShardMeta. func (k *ShardingGroupKeeper) LoadShardMeta(flavor string, enableGTID bool) (map[string]*shardmeta.ShardingMeta, error) { query := fmt.Sprintf("SELECT `target_table_id`, `source_table_id`, `active_index`, `is_global`, `data` FROM %s WHERE `source_id`='%s'", k.shardMetaTableName, k.cfg.SourceID) rows, err := k.dbConn.querySQL(k.tctx, query) @@ -740,7 +740,7 @@ func (k *ShardingGroupKeeper) LoadShardMeta(flavor string, enableGTID bool) (map return meta, terror.WithScope(terror.DBErrorAdapt(rows.Err(), terror.ErrDBDriverError), terror.ScopeDownstream) } -// ShardingReSync represents re-sync info for a sharding DDL group +// ShardingReSync represents re-sync info for a sharding DDL group. type ShardingReSync struct { currLocation binlog.Location // current DDL's binlog location, initialize to first DDL's location latestLocation binlog.Location // latest DDL's binlog location @@ -749,7 +749,7 @@ type ShardingReSync struct { allResolved bool } -// String implements stringer.String +// String implements stringer.String. func (s *ShardingReSync) String() string { return fmt.Sprintf("{schema: %s, table: %s, current location: %v, latest location: %v, all resolved: %v}", s.targetSchema, s.targetTable, s.currLocation, s.latestLocation, s.allResolved) } diff --git a/syncer/sharding_group_test.go b/syncer/sharding_group_test.go index 8ee851425e..eb50d7593a 100644 --- a/syncer/sharding_group_test.go +++ b/syncer/sharding_group_test.go @@ -76,15 +76,18 @@ func (t *testShardingGroupSuite) TestLowestFirstPosInGroups(c *C) { k := NewShardingGroupKeeper(tcontext.Background(), t.cfg) g1 := NewShardingGroup(k.cfg.SourceID, k.shardMetaSchema, k.shardMetaTable, []string{"db1.tbl1", "db1.tbl2"}, nil, false, "", false) + // nolint:dogsled _, _, _, err := g1.TrySync("db1.tbl1", pos11, endPos11, ddls1) c.Assert(err, IsNil) // lowest g2 := NewShardingGroup(k.cfg.SourceID, k.shardMetaSchema, k.shardMetaTable, []string{"db2.tbl1", "db2.tbl2"}, nil, false, "", false) + // nolint:dogsled _, _, _, err = g2.TrySync("db2.tbl1", pos21, endPos21, ddls1) c.Assert(err, IsNil) g3 := NewShardingGroup(k.cfg.SourceID, k.shardMetaSchema, k.shardMetaTable, []string{"db3.tbl1", "db3.tbl2"}, nil, false, "", false) + // nolint:dogsled _, _, _, err = g3.TrySync("db3.tbl1", pos3, endPos3, ddls1) c.Assert(err, IsNil) @@ -125,9 +128,11 @@ func (t *testShardingGroupSuite) TestMergeAndLeave(c *C) { ddls := []string{"DUMMY DDL"} pos1 := mysql.Position{Name: "mysql-bin.000002", Pos: 123} endPos1 := mysql.Position{Name: "mysql-bin.000002", Pos: 456} + // nolint:dogsled _, _, _, err = g1.TrySync(source1, binlog.Location{Position: pos1}, binlog.Location{Position: endPos1}, ddls) c.Assert(err, IsNil) + // nolint:dogsled _, _, _, err = g1.Merge([]string{source1}) c.Assert(terror.ErrSyncUnitAddTableInSharding.Equal(err), IsTrue) err = g1.Leave([]string{source2}) @@ -275,9 +280,11 @@ func (t *testShardingGroupSuite) TestKeeper(c *C) { c.Assert(remain, Equals, 2) // test LeaveGroup + // nolint:dogsled _, _, _, remain, err = k.AddGroup(targetDB, targetTbl, []string{source3}, nil, true) c.Assert(err, IsNil) c.Assert(remain, Equals, 3) + // nolint:dogsled _, _, _, remain, err = k.AddGroup(targetDB, targetTbl, []string{source4}, nil, true) c.Assert(err, IsNil) c.Assert(remain, Equals, 4) diff --git a/syncer/status.go b/syncer/status.go index ca55ff46fa..a3dc64de55 100644 --- a/syncer/status.go +++ b/syncer/status.go @@ -31,7 +31,7 @@ import ( ) // Status implements Unit.Status -// it returns status, but does not calc status +// it returns status, but does not calc status. func (s *Syncer) Status(ctx context.Context) interface{} { var ( masterPos mysql.Position diff --git a/syncer/streamer_controller.go b/syncer/streamer_controller.go index 188c64ede9..ee3fbfd123 100644 --- a/syncer/streamer_controller.go +++ b/syncer/streamer_controller.go @@ -39,12 +39,12 @@ import ( // And we can't simplely use StartSync() method in SteamerProducer // so use generateStreamer to wrap StartSync() method to make *BinlogSyncer and *BinlogReader in same interface // For other implementations who implement StreamerProducer and Streamer can easily take place of Syncer.streamProducer -// For test is easy to mock +// For test is easy to mock. type StreamerProducer interface { generateStreamer(location binlog.Location) (streamer.Streamer, error) } -// Read local relay log +// Read local relay log. type localBinlogReader struct { reader *streamer.BinlogReader EnableGTID bool @@ -57,7 +57,7 @@ func (l *localBinlogReader) generateStreamer(location binlog.Location) (streamer return l.reader.StartSyncByPos(location.Position) } -// Read remote binlog +// Read remote binlog. type remoteBinlogReader struct { reader *replication.BinlogSyncer tctx *tcontext.Context @@ -85,7 +85,7 @@ func (r *remoteBinlogReader) generateStreamer(location binlog.Location) (streame // StreamerController controls the streamer for read binlog, include: // 1. reopen streamer // 2. redirect binlog position or gtid -// 3. transfor from local streamer to remote streamer +// 3. transfor from local streamer to remote streamer. type StreamerController struct { sync.RWMutex @@ -117,7 +117,7 @@ type StreamerController struct { serverIDUpdated bool } -// NewStreamerController creates a new streamer controller +// NewStreamerController creates a new streamer controller. func NewStreamerController(syncCfg replication.BinlogSyncerConfig, enableGTID bool, fromDB *UpStreamConn, binlogType BinlogType, localBinlogDir string, timezone *time.Location) *StreamerController { streamerController := &StreamerController{ initBinlogType: binlogType, @@ -133,7 +133,7 @@ func NewStreamerController(syncCfg replication.BinlogSyncerConfig, enableGTID bo return streamerController } -// Start starts streamer controller +// Start starts streamer controller. func (c *StreamerController) Start(tctx *tcontext.Context, location binlog.Location) error { c.Lock() defer c.Unlock() @@ -156,7 +156,7 @@ func (c *StreamerController) Start(tctx *tcontext.Context, location binlog.Locat return nil } -// ResetReplicationSyncer reset the replication +// ResetReplicationSyncer reset the replication. func (c *StreamerController) ResetReplicationSyncer(tctx *tcontext.Context, location binlog.Location) (err error) { c.Lock() defer c.Unlock() @@ -212,7 +212,7 @@ func (c *StreamerController) resetReplicationSyncer(tctx *tcontext.Context, loca return err } -// RedirectStreamer redirects the streamer's begin position or gtid +// RedirectStreamer redirects the streamer's begin position or gtid. func (c *StreamerController) RedirectStreamer(tctx *tcontext.Context, location binlog.Location) error { c.Lock() defer c.Unlock() @@ -285,7 +285,7 @@ func (c *StreamerController) GetEvent(tctx *tcontext.Context) (event *replicatio return event, nil } -// ReopenWithRetry reopens streamer with retry +// ReopenWithRetry reopens streamer with retry. func (c *StreamerController) ReopenWithRetry(tctx *tcontext.Context, location binlog.Location) error { c.Lock() defer c.Unlock() @@ -328,7 +328,7 @@ func (c *StreamerController) closeBinlogSyncer(logtctx *tcontext.Context, binlog return nil } -// Close closes streamer +// Close closes streamer. func (c *StreamerController) Close(tctx *tcontext.Context) { c.Lock() c.close(tctx) @@ -358,7 +358,7 @@ func (c *StreamerController) close(tctx *tcontext.Context) { c.closed = true } -// IsClosed returns whether streamer controller is closed +// IsClosed returns whether streamer controller is closed. func (c *StreamerController) IsClosed() bool { c.RLock() defer c.RUnlock() @@ -377,7 +377,7 @@ func (c *StreamerController) setUUIDIfExists(filename string) bool { return true } -// UpdateSyncCfg updates sync config and fromDB +// UpdateSyncCfg updates sync config and fromDB. func (c *StreamerController) UpdateSyncCfg(syncCfg replication.BinlogSyncerConfig, fromDB *UpStreamConn) { c.Lock() c.fromDB = fromDB @@ -385,11 +385,12 @@ func (c *StreamerController) UpdateSyncCfg(syncCfg replication.BinlogSyncerConfi c.Unlock() } -// check whether the uuid in binlog position's name is same with upstream +// check whether the uuid in binlog position's name is same with upstream. func (c *StreamerController) checkUUIDSameWithUpstream(ctx context.Context, pos mysql.Position, uuids []string) (bool, error) { _, uuidSuffix, _, err := binlog.SplitFilenameWithUUIDSuffix(pos.Name) if err != nil { // don't contain uuid in position's name + // nolint:nilerr return true, nil } uuid := utils.GetUUIDBySuffix(uuids, uuidSuffix) @@ -402,14 +403,14 @@ func (c *StreamerController) checkUUIDSameWithUpstream(ctx context.Context, pos return uuid == upstreamUUID, nil } -// GetBinlogType returns the binlog type used now +// GetBinlogType returns the binlog type used now. func (c *StreamerController) GetBinlogType() BinlogType { c.RLock() defer c.RUnlock() return c.currentBinlogType } -// CanRetry returns true if can switch from local to remote and retry again +// CanRetry returns true if can switch from local to remote and retry again. func (c *StreamerController) CanRetry() bool { c.RLock() defer c.RUnlock() @@ -433,7 +434,7 @@ func (c *StreamerController) updateServerID(tctx *tcontext.Context) error { return nil } -// UpdateServerIDAndResetReplication updates the server id and reset replication +// UpdateServerIDAndResetReplication updates the server id and reset replication. func (c *StreamerController) UpdateServerIDAndResetReplication(tctx *tcontext.Context, location binlog.Location) error { c.Lock() defer c.Unlock() diff --git a/syncer/streamer_controller_test.go b/syncer/streamer_controller_test.go index d30f8dceff..9626e69d6f 100644 --- a/syncer/streamer_controller_test.go +++ b/syncer/streamer_controller_test.go @@ -14,5 +14,4 @@ func (s *testSyncerSuite) TestIsConnectionRefusedError(c *C) { isConnRefusedErr = isConnectionRefusedError(errors.New("connect: connection refused")) c.Assert(isConnRefusedErr, Equals, true) - } diff --git a/syncer/syncer.go b/syncer/syncer.go index 3f0619161b..5f61a4fe47 100644 --- a/syncer/syncer.go +++ b/syncer/syncer.go @@ -42,6 +42,8 @@ import ( "go.etcd.io/etcd/clientv3" "go.uber.org/zap" + "github.com/pingcap/errors" + "github.com/pingcap/dm/dm/config" "github.com/pingcap/dm/dm/pb" "github.com/pingcap/dm/dm/unit" @@ -62,7 +64,6 @@ import ( operator "github.com/pingcap/dm/syncer/err-operator" sm "github.com/pingcap/dm/syncer/safe-mode" "github.com/pingcap/dm/syncer/shardddl" - "github.com/pingcap/errors" ) var ( @@ -72,7 +73,7 @@ var ( waitTime = 10 * time.Millisecond statusTime = 30 * time.Second - // MaxDDLConnectionTimeoutMinute also used by SubTask.ExecuteDDL + // MaxDDLConnectionTimeoutMinute also used by SubTask.ExecuteDDL. MaxDDLConnectionTimeoutMinute = 5 maxDMLConnectionTimeout = "5m" @@ -84,10 +85,10 @@ var ( defaultBucketCount = 8 ) -// BinlogType represents binlog sync type +// BinlogType represents binlog sync type. type BinlogType uint8 -// binlog sync type +// binlog sync type. const ( RemoteBinlog BinlogType = iota + 1 LocalBinlog @@ -245,7 +246,7 @@ func (s *Syncer) closeJobChans() { s.jobsClosed.Set(true) } -// Type implements Unit.Type +// Type implements Unit.Type. func (s *Syncer) Type() pb.UnitType { return pb.UnitType_Sync } @@ -373,7 +374,7 @@ func (s *Syncer) Init(ctx context.Context) (err error) { } // initShardingGroups initializes sharding groups according to source MySQL, filter rules and router rules -// NOTE: now we don't support modify router rules after task has started +// NOTE: now we don't support modify router rules after task has started. func (s *Syncer) initShardingGroups(ctx context.Context) error { // fetch tables from source and filter them sourceTables, err := s.fromDB.fetchAllDoTables(ctx, s.baList) @@ -423,7 +424,7 @@ func (s *Syncer) initShardingGroups(ctx context.Context) error { return nil } -// IsFreshTask implements Unit.IsFreshTask +// IsFreshTask implements Unit.IsFreshTask. func (s *Syncer) IsFreshTask(ctx context.Context) (bool, error) { globalPoint := s.checkpoint.GlobalPoint() tablePoint := s.checkpoint.TablePoint() @@ -741,9 +742,7 @@ func (s *Syncer) saveTablePoint(db, table string, location binlog.Location) { } func (s *Syncer) addJob(job *job) error { - var ( - queueBucket int - ) + var queueBucket int switch job.tp { case xid: s.saveGlobalPoint(job.location) @@ -779,6 +778,7 @@ func (s *Syncer) addJob(job *job) error { addJobDurationHistogram.WithLabelValues(job.tp.String(), s.cfg.Name, s.queueBucketMapping[queueBucket], s.cfg.SourceID).Observe(time.Since(startTime).Seconds()) } + // nolint:ifshort wait := s.checkWait(job) if wait { s.jobWg.Wait() @@ -786,6 +786,7 @@ func (s *Syncer) addJob(job *job) error { } if s.execError.Get() != nil { + // nolint:nilerr return nil } @@ -869,7 +870,7 @@ func (s *Syncer) resetShardingGroup(schema, table string) { // and except rejecting to flush the checkpoint, we also need to rollback the checkpoint saved before // this should be handled when `s.Run` returned // -// we may need to refactor the concurrency model to make the work-flow more clearer later +// we may need to refactor the concurrency model to make the work-flow more clearer later. func (s *Syncer) flushCheckPoints() error { err := s.execError.Get() // TODO: for now, if any error occurred (including user canceled), checkpoint won't be updated. But if we have put @@ -914,7 +915,7 @@ func (s *Syncer) flushCheckPoints() error { return nil } -// DDL synced one by one, so we only need to process one DDL at a time +// DDL synced one by one, so we only need to process one DDL at a time. func (s *Syncer) syncDDL(tctx *tcontext.Context, queueBucket string, db *DBConn, ddlJobChan chan *job) { defer s.wg.Done() @@ -974,25 +975,27 @@ func (s *Syncer) syncDDL(tctx *tcontext.Context, queueBucket string, db *DBConn, case config.ShardPessimistic: // for sharding DDL syncing, send result back shardInfo := s.pessimist.PendingInfo() - if shardInfo == nil { + switch { + case shardInfo == nil: // no need to do the shard DDL handle for `CREATE DATABASE/TABLE` now. tctx.L().Warn("skip shard DDL handle in pessimistic shard mode", zap.Strings("ddl", sqlJob.ddls)) - } else if shardPessimistOp == nil { + case shardPessimistOp == nil: err = terror.ErrWorkerDDLLockOpNotFound.Generate(shardInfo) - } else { + default: err = s.pessimist.DoneOperationDeleteInfo(*shardPessimistOp, *shardInfo) } case config.ShardOptimistic: shardInfo := s.optimist.PendingInfo() - if shardInfo == nil { + switch { + case shardInfo == nil: // no need to do the shard DDL handle for `DROP DATABASE/TABLE` now. // but for `CREATE DATABASE` and `ALTER DATABASE` we execute it to the downstream directly without `shardInfo`. if ignore { // actually ignored. tctx.L().Warn("skip shard DDL handle in optimistic shard mode", zap.Strings("ddl", sqlJob.ddls)) } - } else if s.optimist.PendingOperation() == nil { + case s.optimist.PendingOperation() == nil: err = terror.ErrWorkerDDLLockOpNotFound.Generate(shardInfo) - } else { + default: err = s.optimist.DoneOperation(*(s.optimist.PendingOperation())) } } @@ -1301,13 +1304,14 @@ func (s *Syncer) Run(ctx context.Context) (err error) { startTime := time.Now() e, err = s.getEvent(tctx, currentLocation) - if err == context.Canceled { + switch { + case err == context.Canceled: tctx.L().Info("binlog replication main routine quit(context canceled)!", zap.Stringer("last location", lastLocation)) return nil - } else if err == context.DeadlineExceeded { + case err == context.DeadlineExceeded: tctx.L().Info("deadline exceeded when fetching binlog event") continue - } else if isDuplicateServerIDError(err) { + case isDuplicateServerIDError(err): // if the server id is already used, need to use a new server id tctx.L().Info("server id is already used by another slave, will change to a new server id and get event again") err1 := s.streamerController.UpdateServerIDAndResetReplication(tctx, lastLocation) @@ -1370,8 +1374,7 @@ func (s *Syncer) Run(ctx context.Context) (err error) { // we calculate startLocation and endLocation(currentLocation) for Query event here // set startLocation empty for other events to avoid misuse startLocation = binlog.Location{} - switch e.Event.(type) { - case *replication.QueryEvent: + if _, ok := e.Event.(*replication.QueryEvent); ok { startLocation = binlog.InitLocation( mysql.Position{ Name: lastLocation.Position.Name, @@ -1423,7 +1426,6 @@ func (s *Syncer) Run(ctx context.Context) (err error) { return err } } - default: } // check pass SafeModeExitLoc and try disable safe mode, but not in sharding or replacing error @@ -1500,8 +1502,7 @@ func (s *Syncer) Run(ctx context.Context) (err error) { job := newXIDJob(currentLocation, startLocation, currentLocation) err2 = s.addJobFunc(job) case *replication.GenericEvent: - switch e.Header.EventType { - case replication.HEARTBEAT_EVENT: + if e.Header.EventType == replication.HEARTBEAT_EVENT { // flush checkpoint even if there are no real binlog events if s.checkpoint.CheckGlobalPoint() { tctx.L().Info("meet heartbeat event and then flush jobs") @@ -1620,7 +1621,7 @@ func (s *Syncer) handleRowsEvent(ev *replication.RowsEvent, ec eventContext) err ec.tctx.L().Debug("", zap.String("event", "row"), zap.String("origin schema", originSchema), zap.String("origin table", originTable), zap.String("target schema", schemaName), zap.String("target table", tableName), log.WrapStringerField("location", ec.currentLocation), zap.Reflect("raw event data", ev.Rows)) if s.cfg.EnableHeartbeat { - s.heartbeat.TryUpdateTaskTs(s.cfg.Name, originSchema, originTable, ev.Rows) + s.heartbeat.TryUpdateTaskTS(s.cfg.Name, originSchema, originTable, ev.Rows) } ignore, err := s.skipDMLEvent(originSchema, originTable, ec.header.EventType) @@ -1814,8 +1815,8 @@ func (s *Syncer) handleQueryEvent(ev *replication.QueryEvent, ec eventContext, o */ var ( ddlInfo *shardingDDLInfo - needHandleDDLs []string - needTrackDDLs []trackedDDL + needHandleDDLs = make([]string, 0, len(sqls)) + needTrackDDLs = make([]trackedDDL, 0, len(sqls)) sourceTbls = make(map[string]map[string]struct{}) // db name -> tb name ) for _, sql := range sqls { @@ -1869,10 +1870,8 @@ func (s *Syncer) handleQueryEvent(ev *replication.QueryEvent, ec eventContext, o tableNames: tableNames, stmt: stmt, } - } else { - if ddlInfo.name != tableNames[0][0].String() { - return terror.ErrSyncerUnitDDLOnMultipleTable.Generate(string(ev.Query)) - } + } else if ddlInfo.name != tableNames[0][0].String() { + return terror.ErrSyncerUnitDDLOnMultipleTable.Generate(string(ev.Query)) } } else if s.cfg.ShardMode == config.ShardOptimistic { switch stmt.(type) { @@ -1949,6 +1948,7 @@ func (s *Syncer) handleQueryEvent(ev *replication.QueryEvent, ec eventContext, o err = s.execError.Get() if err != nil { ec.tctx.L().Error("error detected when executing SQL job", log.ShortError(err)) + // nolint:nilerr return nil } @@ -2135,6 +2135,7 @@ func (s *Syncer) handleQueryEvent(ev *replication.QueryEvent, ec eventContext, o err = s.execError.Get() if err != nil { ec.tctx.L().Error("error detected when executing SQL job", log.ShortError(err)) + // nolint:nilerr return nil } @@ -2150,7 +2151,7 @@ func (s *Syncer) handleQueryEvent(ev *replication.QueryEvent, ec eventContext, o } // input `sql` should be a single DDL, which came from parserpkg.SplitDDL -// tableNames[0] is source (upstream) tableNames, tableNames[1] is target (downstream) tableNames +// tableNames[0] is source (upstream) tableNames, tableNames[1] is target (downstream) tableNames. func (s *Syncer) trackDDL(usedSchema string, sql string, tableNames [][]*filter.Table, stmt ast.StmtNode, ec *eventContext) error { srcTables, targetTables := tableNames[0], tableNames[1] srcTable := srcTables[0] @@ -2195,13 +2196,14 @@ func (s *Syncer) trackDDL(usedSchema string, sql string, tableNames [][]*filter. case *ast.AlterTableStmt: shouldSchemaExist = true // for DDL that adds FK, since TiDB doesn't fully support it yet, we simply ignore execution of this DDL. - if len(node.Specs) == 1 && node.Specs[0].Constraint != nil && node.Specs[0].Constraint.Tp == ast.ConstraintForeignKey { + switch { + case len(node.Specs) == 1 && node.Specs[0].Constraint != nil && node.Specs[0].Constraint.Tp == ast.ConstraintForeignKey: shouldTableExistNum = 1 shouldExecDDLOnSchemaTracker = false - } else if node.Specs[0].Tp == ast.AlterTableRenameTable { + case node.Specs[0].Tp == ast.AlterTableRenameTable: shouldTableExistNum = 1 shouldExecDDLOnSchemaTracker = true - } else { + default: shouldTableExistNum = len(srcTables) shouldExecDDLOnSchemaTracker = true } @@ -2222,6 +2224,7 @@ func (s *Syncer) trackDDL(usedSchema string, sql string, tableNames [][]*filter. } } // skip getTable before in above loop + // nolint:ifshort start := 1 if shouldTableExistNum > start { start = shouldTableExistNum @@ -2449,7 +2452,7 @@ func (s *Syncer) createDBs(ctx context.Context) error { return nil } -// closeBaseDB closes all opened DBs, rollback for createConns +// closeBaseDB closes all opened DBs, rollback for createConns. func (s *Syncer) closeDBs() { closeUpstreamConn(s.tctx, s.fromDB) closeBaseDB(s.tctx, s.toDB) @@ -2457,7 +2460,7 @@ func (s *Syncer) closeDBs() { } // record skip ddl/dml sqls' position -// make newJob's sql argument empty to distinguish normal sql and skips sql +// make newJob's sql argument empty to distinguish normal sql and skips sql. func (s *Syncer) recordSkipSQLsLocation(location binlog.Location) error { job := newSkipJob(location) return s.addJobFunc(job) @@ -2470,8 +2473,7 @@ func (s *Syncer) flushJobs() error { } func (s *Syncer) reSyncBinlog(tctx tcontext.Context, location binlog.Location) error { - err := s.retrySyncGTIDs() - if err != nil { + if err := s.retrySyncGTIDs(); err != nil { return err } // close still running sync @@ -2536,7 +2538,7 @@ func (s *Syncer) Close() { } // stopSync stops syncing, now it used by Close and Pause -// maybe we can refine the workflow more clear +// maybe we can refine the workflow more clear. func (s *Syncer) stopSync() { if s.done != nil { <-s.done // wait Run to return @@ -2580,7 +2582,7 @@ func (s *Syncer) Pause() { s.stopSync() } -// Resume resumes the paused process +// Resume resumes the paused process. func (s *Syncer) Resume(ctx context.Context, pr chan pb.ProcessResult) { if s.isClosed() { s.tctx.L().Warn("try to resume, but already closed") @@ -2605,7 +2607,7 @@ func (s *Syncer) Resume(ctx context.Context, pr chan pb.ProcessResult) { // Update implements Unit.Update // now, only support to update config for routes, filters, column-mappings, block-allow-list -// now no config diff implemented, so simply re-init use new config +// now no config diff implemented, so simply re-init use new config. func (s *Syncer) Update(cfg *config.SubTaskConfig) error { if s.cfg.ShardMode == config.ShardPessimistic { _, tables := s.sgk.UnresolvedTables() @@ -2701,7 +2703,7 @@ func (s *Syncer) Update(cfg *config.SubTaskConfig) error { } // assume that reset master before switching to new master, and only the new master would write -// it's a weak function to try best to fix gtid set while switching master/slave +// it's a weak function to try best to fix gtid set while switching master/slave. func (s *Syncer) retrySyncGTIDs() error { // NOTE: our (per-table based) checkpoint does not support GTID yet, implement it if needed // TODO: support GTID @@ -2709,7 +2711,7 @@ func (s *Syncer) retrySyncGTIDs() error { return nil } -// checkpointID returns ID which used for checkpoint table +// checkpointID returns ID which used for checkpoint table. func (s *Syncer) checkpointID() string { if len(s.cfg.SourceID) > 0 { return s.cfg.SourceID @@ -2717,7 +2719,7 @@ func (s *Syncer) checkpointID() string { return strconv.FormatUint(uint64(s.cfg.ServerID), 10) } -// UpdateFromConfig updates config for `From` +// UpdateFromConfig updates config for `From`. func (s *Syncer) UpdateFromConfig(cfg *config.SubTaskConfig) error { s.Lock() defer s.Unlock() @@ -2830,7 +2832,7 @@ func (s *Syncer) handleEventError(err error, startLocation, endLocation binlog.L return terror.Annotatef(err, "startLocation: [%s], endLocation: [%s]", startLocation, endLocation) } -// getEvent gets an event from streamerController or errOperatorHolder +// getEvent gets an event from streamerController or errOperatorHolder. func (s *Syncer) getEvent(tctx *tcontext.Context, startLocation binlog.Location) (*replication.BinlogEvent, error) { // next event is a replace event if s.isReplacingErr { diff --git a/syncer/syncer_test.go b/syncer/syncer_test.go index 9f358b195f..788db2b128 100644 --- a/syncer/syncer_test.go +++ b/syncer/syncer_test.go @@ -58,22 +58,22 @@ import ( var _ = Suite(&testSyncerSuite{}) -var ( - defaultTestSessionCfg = map[string]string{ - "sql_mode": "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION", - "tidb_skip_utf8_check": "0", - } -) +var defaultTestSessionCfg = map[string]string{ + "sql_mode": "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION", + "tidb_skip_utf8_check": "0", +} func TestSuite(t *testing.T) { TestingT(t) } -type mockBinlogEvents []mockBinlogEvent -type mockBinlogEvent struct { - typ int - args []interface{} -} +type ( + mockBinlogEvents []mockBinlogEvent + mockBinlogEvent struct { + typ int + args []interface{} + } +) const ( DBCreate = iota @@ -204,7 +204,6 @@ func (s *testSyncerSuite) generateEvents(binlogEvents mockBinlogEvents, c *C) [] c.Assert(err, IsNil) events = append(events, evs...) } - } return events } @@ -252,11 +251,13 @@ func (s *testSyncerSuite) TestSelectDB(c *C) { cases = append(cases, Case{ schema: schema, query: append([]byte("create database "), schema...), - skip: skips[i]}) + skip: skips[i], + }) cases = append(cases, Case{ schema: schema, query: append([]byte("drop database "), schema...), - skip: skips[i]}) + skip: skips[i], + }) } db, mock, err := sqlmock.New() @@ -642,7 +643,7 @@ func (s *testSyncerSuite) TestColumnMapping(c *C) { s.resetEventsGenerator(c) - //create db and tables + // create db and tables events := mockBinlogEvents{ mockBinlogEvent{typ: DBCreate, args: []interface{}{"stest_3"}}, mockBinlogEvent{typ: TableCreate, args: []interface{}{"stest_3", "create table stest_3.log(id varchar(45))"}}, @@ -1042,8 +1043,10 @@ func (s *testSyncerSuite) TestRun(c *C) { syncer := NewSyncer(s.cfg, nil) syncer.fromDB = &UpStreamConn{BaseDB: conn.NewBaseDB(db, func() {})} - syncer.toDBConns = []*DBConn{{cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, - {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}} + syncer.toDBConns = []*DBConn{ + {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, + {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, + } syncer.ddlDBConn = &DBConn{cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})} syncer.schemaTracker, err = schema.NewTracker(context.Background(), s.cfg.Name, defaultTestSessionCfg, syncer.ddlDBConn.baseConn) c.Assert(err, IsNil) @@ -1272,8 +1275,10 @@ func (s *testSyncerSuite) TestExitSafeModeByConfig(c *C) { syncer := NewSyncer(s.cfg, nil) syncer.fromDB = &UpStreamConn{BaseDB: conn.NewBaseDB(db, func() {})} - syncer.toDBConns = []*DBConn{{cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, - {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}} + syncer.toDBConns = []*DBConn{ + {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, + {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, + } syncer.ddlDBConn = &DBConn{cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})} syncer.schemaTracker, err = schema.NewTracker(context.Background(), s.cfg.Name, defaultTestSessionCfg, syncer.ddlDBConn.baseConn) c.Assert(err, IsNil) @@ -1411,11 +1416,11 @@ func (s *testSyncerSuite) TestRemoveMetadataIsFine(c *C) { c.Assert(fresh, IsTrue) filename := filepath.Join(s.cfg.Dir, "metadata") - err = ioutil.WriteFile(filename, []byte("SHOW MASTER STATUS:\n\tLog: BAD METADATA"), 0644) + err = ioutil.WriteFile(filename, []byte("SHOW MASTER STATUS:\n\tLog: BAD METADATA"), 0o644) c.Assert(err, IsNil) c.Assert(syncer.checkpoint.LoadMeta(), NotNil) - err = ioutil.WriteFile(filename, []byte("SHOW MASTER STATUS:\n\tLog: mysql-bin.000003\n\tPos: 1234\n\tGTID:\n\n"), 0644) + err = ioutil.WriteFile(filename, []byte("SHOW MASTER STATUS:\n\tLog: mysql-bin.000003\n\tPos: 1234\n\tGTID:\n\n"), 0o644) c.Assert(err, IsNil) c.Assert(syncer.checkpoint.LoadMeta(), IsNil) @@ -1445,8 +1450,10 @@ func (s *testSyncerSuite) TestTrackDDL(c *C) { c.Assert(err, IsNil) syncer := NewSyncer(s.cfg, nil) - syncer.toDBConns = []*DBConn{{cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, - {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}} + syncer.toDBConns = []*DBConn{ + {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, + {cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})}, + } syncer.ddlDBConn = &DBConn{cfg: s.cfg, baseConn: conn.NewBaseConn(dbConn, &retry.FiniteRetryStrategy{})} syncer.checkpoint.(*RemoteCheckPoint).dbConn = &DBConn{cfg: s.cfg, baseConn: conn.NewBaseConn(checkPointDBConn, &retry.FiniteRetryStrategy{})} syncer.schemaTracker, err = schema.NewTracker(context.Background(), s.cfg.Name, defaultTestSessionCfg, syncer.ddlDBConn.baseConn) @@ -1497,7 +1504,7 @@ func (s *testSyncerSuite) TestTrackDDL(c *C) { }}, // 'CREATE TABLE ... SELECT' is not implemented yet - //{fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s AS SELECT * FROM %s, %s.%s WHERE %s.n=%s.%s.n", testDB, testTbl, testTbl2, testDB2, testTbl3, testTbl2, testDB2, testTbl3), func() { + // {fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s AS SELECT * FROM %s, %s.%s WHERE %s.n=%s.%s.n", testDB, testTbl, testTbl2, testDB2, testTbl3, testTbl2, testDB2, testTbl3), func() { // mock.ExpectQuery("SHOW VARIABLES LIKE 'sql_mode'").WillReturnRows( // sqlmock.NewRows([]string{"Variable_name", "Value"}).AddRow("sql_mode", "")) // mock.ExpectQuery(fmt.Sprintf("SHOW CREATE TABLE \\`%s\\`.\\`%s\\`.*", testDB, testTbl2)).WillReturnRows( @@ -1508,7 +1515,7 @@ func (s *testSyncerSuite) TestTrackDDL(c *C) { // mock.ExpectQuery(fmt.Sprintf("SHOW CREATE TABLE \\`%s\\`.\\`%s\\`.*", testDB2, testTbl3)).WillReturnRows( // sqlmock.NewRows([]string{"Table", "Create Table"}). // AddRow(testTbl, " CREATE TABLE `"+testTbl+"` (\n `c` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - //}}, + // }}, // test RENAME TABLE {fmt.Sprintf("RENAME TABLE %s.%s TO %s.%s", testDB, testTbl, testDB, testTbl2), func() { diff --git a/syncer/util.go b/syncer/util.go index c264e71e3f..9b7aef4ddb 100644 --- a/syncer/util.go +++ b/syncer/util.go @@ -44,7 +44,7 @@ func binlogTypeToString(binlogType BinlogType) string { } } -// tableNameForDML gets table name from INSERT/UPDATE/DELETE statement +// tableNameForDML gets table name from INSERT/UPDATE/DELETE statement. func tableNameForDML(dml ast.DMLNode) (schema, table string, err error) { switch stmt := dml.(type) { case *ast.InsertStmt: @@ -103,7 +103,7 @@ func getDBConfigFromEnv() config.DBConfig { } } -// record source tbls record the tables that need to flush checkpoints +// record source tbls record the tables that need to flush checkpoints. func recordSourceTbls(sourceTbls map[string]map[string]struct{}, stmt ast.StmtNode, table *filter.Table) { schema, name := table.Schema, table.Name switch stmt.(type) { diff --git a/syncer/util_test.go b/syncer/util_test.go index f693c39d2f..e921d08dfc 100644 --- a/syncer/util_test.go +++ b/syncer/util_test.go @@ -24,8 +24,7 @@ import ( var _ = Suite(&testUtilSuite{}) -type testUtilSuite struct { -} +type testUtilSuite struct{} func (t *testUtilSuite) TestTableNameForDML(c *C) { cases := []struct { diff --git a/tests/ha_cases/run.sh b/tests/ha_cases/run.sh index aca1daa7d5..6ec6215a87 100755 --- a/tests/ha_cases/run.sh +++ b/tests/ha_cases/run.sh @@ -803,6 +803,7 @@ function test_last_bound() { function run() { test_last_bound + read v1 test_config_name # TICASE-915, 916, 954, 955 test_join_masters_and_worker # TICASE-928, 930, 931, 961, 932, 957 test_kill_master # TICASE-996, 958 diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000000..28de20dc97 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,28 @@ +all: failpoint-ctl gocovmerge goveralls golangci-lint mockgen protoc-gen-gogofaster protoc-gen-grpc-gateway statik gofumports + +failpoint-ctl: + go build -o bin/$@ github.com/pingcap/failpoint/failpoint-ctl + +gocovmerge: + go build -o bin/$@ github.com/zhouqiang-cl/gocovmerge + +goveralls: + go build -o bin/$@ github.com/mattn/goveralls + +golangci-lint: + go build -o bin/$@ github.com/golangci/golangci-lint/cmd/golangci-lint + +mockgen: + go build -o bin/$@ github.com/golang/mock/mockgen + +protoc-gen-gogofaster: + go build -o bin/$@ github.com/gogo/protobuf/protoc-gen-gogofaster + +protoc-gen-grpc-gateway: + go build -o bin/$@ github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway + +statik: + go build -o bin/$@ github.com/rakyll/statik + +gofumports: + go build -o bin/$@ mvdan.cc/gofumpt/gofumports diff --git a/tools/go.mod b/tools/go.mod index 6a4eeea47f..ca836649e3 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -3,12 +3,13 @@ module github.com/pingcap/dm/tools go 1.13 require ( - github.com/gogo/protobuf v1.3.1 // indirect - github.com/golang/mock v1.3.1 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.12.1 // indirect - github.com/mattn/goveralls v0.0.4 // indirect - github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce // indirect - github.com/rakyll/statik v0.1.6 // indirect - github.com/zhouqiang-cl/gocovmerge v0.0.0-20190125174600-5256314471af // indirect - golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect + github.com/gogo/protobuf v1.3.2 + github.com/golang/mock v1.5.0 + github.com/golangci/golangci-lint v1.39.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/mattn/goveralls v0.0.8 + github.com/pingcap/failpoint v0.0.0-20210316064728-7acb0f0a3dfd + github.com/rakyll/statik v0.1.7 + github.com/zhouqiang-cl/gocovmerge v0.0.0-20190125174600-5256314471af + mvdan.cc/gofumpt v0.1.1 ) diff --git a/tools/go.sum b/tools/go.sum index a2dd777594..f52cec0a96 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -1,85 +1,1067 @@ +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w= +cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= +github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/ashanbrown/forbidigo v1.1.0 h1:SJOPJyqsrVL3CvR0veFZFmIM0fXS/Kvyikqvfphd0Z4= +github.com/ashanbrown/forbidigo v1.1.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/makezero v0.0.0-20210308000810-4155955488a0 h1:27owMIbvO33XL56BKWPy+SCU69I9wPwPXuMf5mAbVGU= +github.com/ashanbrown/makezero v0.0.0-20210308000810-4155955488a0/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= +github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= +github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/bombsimon/wsl/v3 v3.2.0 h1:x3QUbwW7tPGcCNridvqmhSRthZMTALnkg5/1J+vaUas= +github.com/bombsimon/wsl/v3 v3.2.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charithe/durationcheck v0.0.6 h1:Tsy7EppNow2pDC0jN7Hsmcb6mHd71ZbI1vFissRBtc0= +github.com/charithe/durationcheck v0.0.6/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/daixiang0/gci v0.2.8 h1:1mrIGMBQsBu0P7j7m1M8Lb+ZeZxsZL+jyGX4YoMJJpg= +github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= +github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= +github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/esimonov/ifshort v1.0.2 h1:K5s1W2fGfkoWXsFlxBNqT6J0ZCncPaKrGM5qe0bni68= +github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= +github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc= +github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/go-critic/go-critic v0.5.5 h1:hqPHqQt/2l4Syc2VOIgcuy0FSytcbatOHWggu45vhw8= +github.com/go-critic/go-critic v0.5.5/go.mod h1:eMs1Oc/oIP+CYNVN09M+XZYffIPuRHawxzlggAPN9Kk= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= +github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= +github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= +github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= +github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= +github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.39.0 h1:aAUjdBxARwkGLd5PU0vKuym281f2rFOyqh3GB4nXcq8= +github.com/golangci/golangci-lint v1.39.0/go.mod h1:mzMK3FGyk8LKTOxpRDcDqxwHVudnYemESTt5rpUxqCM= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= +github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5 h1:c9Mqqrm/Clj5biNaG7rABrmwUq88nHh0uABo2b/WYmc= +github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw= +github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gookit/color v1.3.8/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI= +github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw= +github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= +github.com/gostaticanalysis/analysisutil v0.4.1 h1:/7clKqrVfiVwiBQLM0Uke4KvXnO6JcCTS7HwF2D6wG8= +github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= +github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5 h1:rx8127mFPqXXsfPSo8BwnIU97MKFZc89WHAHt8PwDVY= +github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= -github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jgautheron/goconst v1.4.0 h1:hp9XKUpe/MPyDamUbfsrGpe+3dnY2whNK4EtB86dvLM= +github.com/jgautheron/goconst v1.4.0/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= +github.com/jingyugao/rowserrcheck v0.0.0-20210315055705-d907ca737bb1 h1:4Rlb26NqzNtbDH69CRpr0vZooj3jAlXTycWCX3xRYAY= +github.com/jingyugao/rowserrcheck v0.0.0-20210315055705-d907ca737bb1/go.mod h1:TOQpc2SLx6huPfoFGK3UOnEG+u02D3C1GeosjupAKCA= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julz/importas v0.0.0-20210228071311-d0bf5cb4e1db h1:ZmwBthGFMVAieuVpLzuedUH9l4pY/0iFG16DN9dS38o= +github.com/julz/importas v0.0.0-20210228071311-d0bf5cb4e1db/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY= +github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/mattn/goveralls v0.0.4 h1:/mdWfiU2y8kZ48EtgByYev/XT3W4dkTuKLOJJsh/r+o= -github.com/mattn/goveralls v0.0.4/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.4.0 h1:2Nx7XbdbE/BYZeoip2mURKUdtHQRuy6Ug+wR7K9ywNM= +github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= +github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= +github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/ldez/gomoddirectives v0.2.1 h1:9pAcW9KRZW7HQjFwbozNvFMcNVwdCBufU7os5QUwLIY= +github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4= +github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= +github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mattn/goveralls v0.0.8 h1:4xflElRkVgj/FcBVKTAkqSWhHFY2u2uv4c054kG2RY8= +github.com/mattn/goveralls v0.0.8/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= +github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM= +github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= +github.com/mgechev/revive v1.0.5 h1:cTDWX83qkDajREg4GO0sQcYrjJtSSh3308DWJzpnUqg= +github.com/mgechev/revive v1.0.5/go.mod h1:tSw34BaGZ0iF+oVKDOjq1/LuxGifgW7shaJ6+dBYFXg= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= +github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= +github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= +github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= +github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= +github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= +github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= +github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= +github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= +github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= +github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg= github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce h1:Y1kCxlCtlPTMtVcOkjUcuQKh+YrluSo7+7YMCQSzy30= -github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce/go.mod h1:w4PEZ5y16LeofeeGwdgZB4ddv9bLyDuIX+ljstgKZyk= +github.com/pingcap/failpoint v0.0.0-20210316064728-7acb0f0a3dfd h1:I8IeI8MNiZVKnwuXhcIIzz6pREcOSbq18Q31KYIzFVM= +github.com/pingcap/failpoint v0.0.0-20210316064728-7acb0f0a3dfd/go.mod h1:IVF+ijPSMZVtx2oIqxAg7ur6EyixtTYfOHwpfmlhqI4= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rakyll/statik v0.1.6 h1:uICcfUXpgqtw2VopbIncslhAmE5hwc4g20TEyEENBNs= -github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= +github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f h1:xAw10KgJqG5NJDfmRqJ05Z0IFblKumjtMeyiOLxj3+4= +github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= +github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= +github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= +github.com/quasilyte/go-ruleguard v0.3.1 h1:2KTXnHBCR4BUl8UAL2bCUorOBGC8RsmYncuDA9NEFW4= +github.com/quasilyte/go-ruleguard v0.3.1/go.mod h1:s41wdpioTcgelE3dlTUgK57UaUxjihg/DBGUccoN5IU= +github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.1/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20210221215616-dfcc94e3dffd/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= +github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44 h1:tB9NOR21++IjLyVx3/PCPhWMwqGNCMQEH96A6dMZ/gc= -github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= +github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.2.0 h1:YWfhGOrXwLGiqcC/u5EqG6YeS8nh+1fw0HEc85CVZro= +github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= +github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sanposhiho/wastedassign v0.2.0 h1:0vycy8D/Ky55U5ub8oJFqyDv9M4ICM/wte9sAp2/7Mc= +github.com/sanposhiho/wastedassign v0.2.0/go.mod h1:LGpq5Hsv74QaqM47WtIsRSF/ik9kqk07kchgv66tLVE= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/securego/gosec/v2 v2.7.0 h1:mOhJv5w6UyNLpSssQOQCc7eGkKLuicAxvf66Ey/X4xk= +github.com/securego/gosec/v2 v2.7.0/go.mod h1:xNbGArrGUspJLuz3LS5XCY1EBW/0vABAl/LWfSklmiM= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= +github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tetafro/godot v1.4.4 h1:VAtLEoAMmopIzHVWVBrztjVWDeYm1OD/DKqhqXR4828= +github.com/tetafro/godot v1.4.4/go.mod h1:FVDd4JuKliW3UgjswZfJfHq4vAx0bD/Jd5brJjGeaz4= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tomarrell/wrapcheck v1.0.0 h1:e/6yv/rH08TZFvkYpaAMrgGbaQHVFdzaPPv4a5EIu+o= +github.com/tomarrell/wrapcheck v1.0.0/go.mod h1:Bd3i1FaEKe3XmcPoHhNQ+HM0S8P6eIXoQIoGj/ndJkU= +github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= +github.com/tommy-muehle/go-mnd/v2 v2.3.1 h1:a1S4+4HSXDJMgeODJH/t0EEKxcVla6Tasw+Zx9JJMog= +github.com/tommy-muehle/go-mnd/v2 v2.3.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= +github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= +github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= +github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zhouqiang-cl/gocovmerge v0.0.0-20190125174600-5256314471af h1:TscntfU6Necy6hfH+hcow8QSg8DJq47Fe/rqpZZS9U4= github.com/zhouqiang-cl/gocovmerge v0.0.0-20190125174600-5256314471af/go.mod h1:Zot6ZD+7MXm1DzYOkmHNMcq72CRIdbh1qSsEbaxhHgY= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= +go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 h1:V066+OYJ66oTjnhm4Yrn7SXIwSCiDQJxpBxmvqb1N1c= +golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262 h1:qsl9y/CJx34tuA7QCPNp86JNJe4spst6Ff8MjvPUdPg= +golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f h1:kDxGY2VmgABOe55qheT/TFqUMtcTHnomIPS1iv3G4Ms= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo= +google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df h1:HWF6nM8ruGdu1K8IXFR+i2oT3YP+iBfZzCbC9zUfcWo= +google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA= +mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7 h1:HT3e4Krq+IE44tiN36RvVEb6tvqeIdtsVSsxmNPqlFU= +mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/tools/tools.go b/tools/tools.go index 7c2390ab59..402c7b66d9 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -19,14 +19,15 @@ package tools import ( + // make go module happy _ "github.com/gogo/protobuf/protoc-gen-gogofaster" _ "github.com/golang/mock/mockgen" + _ "github.com/golangci/golangci-lint/pkg/commands" _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway" - _ "github.com/kisielk/errcheck" _ "github.com/mattn/goveralls" _ "github.com/pingcap/failpoint" _ "github.com/rakyll/statik" _ "github.com/zhouqiang-cl/gocovmerge" - _ "golang.org/x/lint/golint" + _ "mvdan.cc/gofumpt/gofumports" )