Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: Introduce version checking mechanism #1148

Merged
merged 37 commits into from
Jul 24, 2018
Merged

Conversation

nolouch
Copy link
Contributor

@nolouch nolouch commented Jul 13, 2018

What have you changed? (required)

Our system guarantees backward compatibility. But there is a compatibility problem after change RaftCommand. Almost every small change in RaftComand of TiKV requires a proper way to rolling upgrade.

What are the type of the changes (required)?

  • New feature

How has this PR been tested (required)?

unit tests
integration tests
manual tests

Does this PR affect documentation (docs/docs-cn) update? (optional)

Refer to a related PR or issue link (optional)

VersionBatchSplit: {Marjor: 2, Minor: 1},
}

// TargetVersion get target version by version featrue
Copy link
Member

Choose a reason for hiding this comment

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

s/featrue/feature/


// Version record version information.
type Version struct {
Marjor int32
Copy link
Member

Choose a reason for hiding this comment

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

s/Marjor/Major/


//ParseVersion parses a version from a string.
//The string format should be "major.minor.patch-<unstable>".
func ParseVersion(s string) (Version, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

em, why not using a 3rd lib?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to suggest using https://godoc.org/github.com/coreos/go-semver or https://godoc.org/github.com/blang/semver, not know their difference through.

@@ -108,6 +108,7 @@ func (kv *KV) DeleteRegion(region *metapb.Region) error {
// SaveConfig stores marshalable cfg to the configPath.
func (kv *KV) SaveConfig(cfg interface{}) error {
value, err := json.Marshal(cfg)
fmt.Println("pesist config:", string(value))
Copy link
Contributor

Choose a reason for hiding this comment

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

why print ?

Copy link
Contributor

Choose a reason for hiding this comment

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

pesist -> persist

// Version Fetures.
const (
VersionBase VersionFeature = iota
VersionRegionMergeAndRaftLearner
Copy link
Contributor

Choose a reason for hiding this comment

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

em, too long...

Btw, they are two different things, why not using two version?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I would suggest changing from VersionFeature to just Feature and here splitting these into two features. The featuresDict can map them both to the same version. I would also remove VersionBase.

}

// IsSupport check if support the features.
func (c *clusterInfo) IsSupport(f VersionFeature) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

IsSuport -> IsSupported

)

// VersionFeature is a unique identifier for minimum support version.
type VersionFeature int
Copy link
Contributor

Choose a reason for hiding this comment

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

Using ordinal int can lead to merge conflicts. This is part of the reason why I used string in my error code PR.

// Version Fetures.
const (
VersionBase VersionFeature = iota
VersionRegionMergeAndRaftLearner
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I would suggest changing from VersionFeature to just Feature and here splitting these into two features. The featuresDict can map them both to the same version. I would also remove VersionBase.

@@ -108,6 +108,7 @@ func (kv *KV) DeleteRegion(region *metapb.Region) error {
// SaveConfig stores marshalable cfg to the configPath.
func (kv *KV) SaveConfig(cfg interface{}) error {
value, err := json.Marshal(cfg)
fmt.Println("pesist config:", string(value))
Copy link
Contributor

Choose a reason for hiding this comment

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

pesist -> persist

//The string format should be "major.minor.patch-<unstable>".
func ParseVersion(s string) (Version, error) {
if s == "" {
return TargetVersion(VersionBase), nil
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be an error. Otherwise this may silently work when something is wrong. The caller can have different logic to get a default version if it doesn't actually have a version string.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we need to make it compatible with old tikv server which does not send version when rolling update a online cluster.

@@ -218,6 +218,7 @@ func (s *Server) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (*
}

log.Infof("put store ok - %v", store)
cluster.cachedCluster.OnChangeClusterVersion()
Copy link
Contributor

Choose a reason for hiding this comment

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

If the machine crashes before here will the cluster version not get updated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. I need to handle this situation.

Copy link
Contributor

Choose a reason for hiding this comment

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

How about OnStoreVersionChange?

Copy link
Contributor Author

@nolouch nolouch Jul 17, 2018

Choose a reason for hiding this comment

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

@gregwebs I reconsider it. The cluster version will not get updated if meet crashes before here. but also the corresponding TiKV will not start up. it will register in next time when restarting TiKV and get the update.

Major int32
Minor int32
Patch int32
Unstable int32
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it should be PreRelease instead of Unstable.
See: https://semver.org/#spec-item-9 and https://godoc.org/github.com/coreos/go-semver/semver#Version

convMap := map[int32]string{
1: "alpha",
2: "beta",
3: "rc",
Copy link
Contributor

Choose a reason for hiding this comment

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

In fact the pre-release version can be any string contains [0-9A-Za-z-]. See https://semver.org/#spec-item-9

if s.IsTombstone() {
continue
}
if i == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be clearer to move this to after the v assignment as if i==0 || v.LessThan(minVersion).

}
}

// IsSupported check if support the feature.
Copy link
Contributor

Choose a reason for hiding this comment

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

IsSupported checks if the feature is supported by current cluster.

Copy link
Contributor

Choose a reason for hiding this comment

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

how about IsFeatureSupported?

if clusterVersion.LessThan(minSupportVersion) {
return false
}
return true
Copy link
Contributor

Choose a reason for hiding this comment

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

return !clusterVersion.LessThan(minSupportVersion)

@@ -218,6 +218,7 @@ func (s *Server) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (*
}

log.Infof("put store ok - %v", store)
cluster.cachedCluster.OnChangeClusterVersion()
Copy link
Contributor

Choose a reason for hiding this comment

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

How about OnStoreVersionChange?

if i == 0 {
minVersion = *MustParseVersion(s.GetVersion())
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The first store can be tombstone state.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can let minVersion = *semver.Version and use if minVersion == nil || v.LessThen(minVersion) to compare.

@nolouch nolouch added the status/tests-passed The PR has passed all tests. label Jul 18, 2018
@nolouch
Copy link
Contributor Author

nolouch commented Jul 18, 2018

PTAL.

}
version, ok := input["cluster-version"]
if !ok {
h.rd.JSON(w, http.StatusInternalServerError, "not set cluster version")
Copy link
Contributor

Choose a reason for hiding this comment

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

Use 400 instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

Message should use the exact key name "cluster-version". A helper function for this case would create consistent messages.

server/server.go Outdated
return errors.Trace(err)
}
s.scheduleOpt.SetClusterVersion(*version)
s.scheduleOpt.persist(s.kv)
Copy link
Contributor

Choose a reason for hiding this comment

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

Unchecked return value?

Copy link
Contributor

Choose a reason for hiding this comment

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

There are at least 4 other instances of not checking the return value for this in the same file. I am going to try to setup errcheck efficiently, but I may not finish that until next week. But here is a simple check of the server code: #1152

Version2_0
RegionMerge
RaftLearner
BatchSplit
Copy link
Contributor

Choose a reason for hiding this comment

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

Better to add some comments to describe the meaning of these features.

RegionMerge: {Major: 2, Minor: 0},
RaftLearner: {Major: 2, Minor: 0},
BatchSplit: {Major: 2, Minor: 1},
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Will it be more readable to use string style? like BatchSplit: "v2.1.0".

server/server.go Outdated
err = s.scheduleOpt.persist(s.kv)
if err != nil {
return errors.Trace(err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you want to update the version before persisting it.

server/server.go Outdated
if err != nil {
return errors.Trace(err)
}
s.scheduleOpt.SetClusterVersion(*version)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you want to update the version before persisting it.

// ParseVersion wraps semver.NewVersion and handles compatibility issues.
func ParseVersion(v string) (*semver.Version, error) {
// for compatibility with old version which not support `version` mechanism.
baseVersion := semver.New(featuresDict[Base])
Copy link
Contributor

Choose a reason for hiding this comment

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

you can create the base version in the if clause.

minVersion = v
}
}
if clusterVersion.LessThan(*minVersion) {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we meet the case that PD itself's version is less than the min version?

Copy link
Contributor Author

@nolouch nolouch Jul 19, 2018

Choose a reason for hiding this comment

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

Yes. but PD just provides currently knows features. so the cluster still running with lower version features. I think it's normal behavior because the cluster upgrade not finished. Maybe I need to warn it.

Copy link
Contributor

Choose a reason for hiding this comment

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

em, if PD's version is older, it should not be able to provide service for the features that it does not have.

@disksing
Copy link
Contributor

LGTM.

@nolouch
Copy link
Contributor Author

nolouch commented Jul 24, 2018

PTAL @siddontang @rleungx

@nolouch nolouch merged commit 6cf335f into tikv:master Jul 24, 2018
@nolouch nolouch deleted the version-introduce branch July 24, 2018 13:01
nolouch added a commit to nolouch/pd that referenced this pull request Aug 15, 2018
ti-chi-bot pushed a commit that referenced this pull request Feb 15, 2023
…1.11.1 in /tools/pd-tso-bench (#5990)

ref #897, ref #962, ref #969, ref #974, ref #975, ref #976, ref #986, ref prometheus/client_golang#987, ref #987, ref #989, ref #998, ref #1013, ref #1014, ref #1025, ref #1028, ref #1031, ref #1043, ref #1055, ref #1075, ref #1091, ref #1094, ref #1102, ref #1103, ref #1118, ref #1146, ref #1148, ref #1150

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ti-chi-bot pushed a commit to lhy1024/pd that referenced this pull request Feb 15, 2023
…1.11.1 in /tests/client (tikv#5992)

ref tikv#897, ref tikv#962, ref tikv#969, ref tikv#974, ref tikv#975, ref tikv#976, ref tikv#986, ref tikv#987, ref prometheus/client_golang#987, ref tikv#989, ref tikv#998, ref tikv#1013, ref tikv#1014, ref tikv#1025, ref tikv#1028, ref tikv#1031, ref tikv#1043, ref tikv#1055, ref tikv#1075, ref tikv#1091, ref tikv#1094, ref tikv#1102, ref tikv#1103, ref tikv#1118, ref tikv#1146, ref tikv#1148, ref tikv#1150, ref tikv#4399

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ti-chi-bot added a commit that referenced this pull request Feb 15, 2023
…1.11.1 in /tests/mcs (#5993)

ref #897, ref #962, ref #969, ref #974, ref #975, ref #976, ref #986, ref #987, ref prometheus/client_golang#987, ref #989, ref #998, ref #1013, ref #1014, ref #1025, ref #1028, ref #1031, ref #1043, ref #1055, ref #1075, ref #1091, ref #1094, ref #1102, ref #1103, ref #1118, ref #1146, ref #1148, ref #1150, ref #4399

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ti Chi Robot <ti-community-prow-bot@tidb.io>
ti-chi-bot added a commit that referenced this pull request Feb 15, 2023
…1.11.1 in /client (#5991)

ref #897, ref #962, ref #969, ref #974, ref #975, ref #976, ref #986, ref #987, ref prometheus/client_golang#987, ref #989, ref #998, ref #1013, ref #1014, ref #1025, ref #1028, ref #1031, ref #1043, ref #1055, ref #1075, ref #1091, ref #1094, ref #1102, ref #1103, ref #1118, ref #1146, ref #1148, ref #1150, ref #4399

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ti Chi Robot <ti-community-prow-bot@tidb.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/tests-passed The PR has passed all tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants