-
Notifications
You must be signed in to change notification settings - Fork 721
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
Conversation
server/version.go
Outdated
VersionBatchSplit: {Marjor: 2, Minor: 1}, | ||
} | ||
|
||
// TargetVersion get target version by version featrue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/featrue/feature/
server/version.go
Outdated
|
||
// Version record version information. | ||
type Version struct { | ||
Marjor int32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Marjor/Major/
server/version.go
Outdated
|
||
//ParseVersion parses a version from a string. | ||
//The string format should be "major.minor.patch-<unstable>". | ||
func ParseVersion(s string) (Version, error) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
server/core/kv.go
Outdated
@@ -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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why print ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pesist -> persist
server/version.go
Outdated
// Version Fetures. | ||
const ( | ||
VersionBase VersionFeature = iota | ||
VersionRegionMergeAndRaftLearner |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
server/cluster_info.go
Outdated
} | ||
|
||
// IsSupport check if support the features. | ||
func (c *clusterInfo) IsSupport(f VersionFeature) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IsSuport -> IsSupported
server/version.go
Outdated
) | ||
|
||
// VersionFeature is a unique identifier for minimum support version. | ||
type VersionFeature int |
There was a problem hiding this comment.
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.
server/version.go
Outdated
// Version Fetures. | ||
const ( | ||
VersionBase VersionFeature = iota | ||
VersionRegionMergeAndRaftLearner |
There was a problem hiding this comment.
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
.
server/core/kv.go
Outdated
@@ -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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pesist -> persist
server/version.go
Outdated
//The string format should be "major.minor.patch-<unstable>". | ||
func ParseVersion(s string) (Version, error) { | ||
if s == "" { | ||
return TargetVersion(VersionBase), nil |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
server/grpc_service.go
Outdated
@@ -218,6 +218,7 @@ func (s *Server) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (* | |||
} | |||
|
|||
log.Infof("put store ok - %v", store) | |||
cluster.cachedCluster.OnChangeClusterVersion() |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about OnStoreVersionChange
?
There was a problem hiding this comment.
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.
server/version.go
Outdated
Major int32 | ||
Minor int32 | ||
Patch int32 | ||
Unstable int32 |
There was a problem hiding this comment.
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
server/version.go
Outdated
convMap := map[int32]string{ | ||
1: "alpha", | ||
2: "beta", | ||
3: "rc", |
There was a problem hiding this comment.
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
server/cluster_info.go
Outdated
if s.IsTombstone() { | ||
continue | ||
} | ||
if i == 0 { |
There was a problem hiding this comment.
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)
.
server/cluster_info.go
Outdated
} | ||
} | ||
|
||
// IsSupported check if support the feature. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about IsFeatureSupported
?
server/cluster_info.go
Outdated
if clusterVersion.LessThan(minSupportVersion) { | ||
return false | ||
} | ||
return true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return !clusterVersion.LessThan(minSupportVersion)
server/grpc_service.go
Outdated
@@ -218,6 +218,7 @@ func (s *Server) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (* | |||
} | |||
|
|||
log.Infof("put store ok - %v", store) | |||
cluster.cachedCluster.OnChangeClusterVersion() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about OnStoreVersionChange
?
server/cluster_info.go
Outdated
if i == 0 { | ||
minVersion = *MustParseVersion(s.GetVersion()) | ||
continue | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
PTAL. |
server/api/config.go
Outdated
} | ||
version, ok := input["cluster-version"] | ||
if !ok { | ||
h.rd.JSON(w, http.StatusInternalServerError, "not set cluster version") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use 400 instead.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unchecked return value?
There was a problem hiding this comment.
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
server/version.go
Outdated
Version2_0 | ||
RegionMerge | ||
RaftLearner | ||
BatchSplit |
There was a problem hiding this comment.
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.
server/version.go
Outdated
RegionMerge: {Major: 2, Minor: 0}, | ||
RaftLearner: {Major: 2, Minor: 0}, | ||
BatchSplit: {Major: 2, Minor: 1}, | ||
} |
There was a problem hiding this comment.
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) | ||
} |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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/version.go
Outdated
// 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]) |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
LGTM. |
PTAL @siddontang @rleungx |
…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] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…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] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…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] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ti Chi Robot <[email protected]>
…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] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ti Chi Robot <[email protected]>
What have you changed? (required)
Our system guarantees backward compatibility. But there is a compatibility problem after change
RaftCommand
. Almost every small change inRaftComand
of TiKV requires a proper way to rolling upgrade.What are the type of the changes (required)?
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)