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

tools: add merge commands for pd-ctl #6675

Merged
merged 3 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions tests/pdctl/keyspace/keyspace_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,76 @@ func TestSetNodeAndPriorityKeyspaceGroup(t *testing.T) {
re.NoError(err)
re.Contains(string(output), "Failed to parse the priority")
}

func TestMergeKeyspaceGroup(t *testing.T) {
re := require.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
re.NoError(failpoint.Enable("github.com/tikv/pd/pkg/keyspace/acceleratedAllocNodes", `return(true)`))
re.NoError(failpoint.Enable("github.com/tikv/pd/server/delayStartServerLoop", `return(true)`))
keyspaces := make([]string, 0)
// we test the case which exceed the default max txn ops limit in etcd, which is 128.
for i := 0; i < 129; i++ {
keyspaces = append(keyspaces, fmt.Sprintf("keyspace_%d", i))
}
tc, err := tests.NewTestAPICluster(ctx, 3, func(conf *config.Config, serverName string) {
conf.Keyspace.PreAlloc = keyspaces
})
re.NoError(err)
err = tc.RunInitialServers()
re.NoError(err)
pdAddr := tc.GetConfig().GetClientURL()

_, tsoServerCleanup1, err := tests.StartSingleTSOTestServer(ctx, re, pdAddr, tempurl.Alloc())
defer tsoServerCleanup1()
re.NoError(err)
_, tsoServerCleanup2, err := tests.StartSingleTSOTestServer(ctx, re, pdAddr, tempurl.Alloc())
defer tsoServerCleanup2()
re.NoError(err)
cmd := pdctlCmd.GetRootCmd()

tc.WaitLeader()
leaderServer := tc.GetServer(tc.GetLeader())
re.NoError(leaderServer.BootstrapCluster())

// split keyspace group.
testutil.Eventually(re, func() bool {
args := []string{"-u", pdAddr, "keyspace-group", "split", "0", "1", "2"}
output, err := pdctl.ExecuteCommand(cmd, args...)
re.NoError(err)
return strings.Contains(string(output), "Success")
})

args := []string{"-u", pdAddr, "keyspace-group", "finish-split", "0"}
output, err := pdctl.ExecuteCommand(cmd, args...)
re.NoError(err)
strings.Contains(string(output), "Success")
args = []string{"-u", pdAddr, "keyspace-group", "finish-split", "1"}
output, err = pdctl.ExecuteCommand(cmd, args...)
re.NoError(err)
strings.Contains(string(output), "Success")

// merge keyspace group.
testutil.Eventually(re, func() bool {
args := []string{"-u", pdAddr, "keyspace-group", "merge", "0", "1"}
output, err := pdctl.ExecuteCommand(cmd, args...)
re.NoError(err)
return strings.Contains(string(output), "Success")
})

args = []string{"-u", pdAddr, "keyspace-group", "finish-merge", "0"}
output, err = pdctl.ExecuteCommand(cmd, args...)
re.NoError(err)
strings.Contains(string(output), "Success")
args = []string{"-u", pdAddr, "keyspace-group", "0"}
output, err = pdctl.ExecuteCommand(cmd, args...)
re.NoError(err)
var keyspaceGroup endpoint.KeyspaceGroup
err = json.Unmarshal(output, &keyspaceGroup)
re.NoError(err)
re.Len(keyspaceGroup.Keyspaces, 130)
re.Nil(keyspaceGroup.MergeState)

re.NoError(failpoint.Disable("github.com/tikv/pd/pkg/keyspace/acceleratedAllocNodes"))
re.NoError(failpoint.Disable("github.com/tikv/pd/server/delayStartServerLoop"))
}
90 changes: 90 additions & 0 deletions tools/pd-ctl/pdctl/command/keyspace_group_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
Run: showKeyspaceGroupCommandFunc,
}
cmd.AddCommand(newSplitKeyspaceGroupCommand())
cmd.AddCommand(newFinishSplitKeyspaceGroupCommand())
cmd.AddCommand(newMergeKeyspaceGroupCommand())
cmd.AddCommand(newFinishMergeKeyspaceGroupCommand())
cmd.AddCommand(newSetNodesKeyspaceGroupCommand())
cmd.AddCommand(newSetPriorityKeyspaceGroupCommand())
return cmd
Expand All @@ -47,6 +50,33 @@
return r
}

func newFinishSplitKeyspaceGroupCommand() *cobra.Command {
Copy link
Contributor

Choose a reason for hiding this comment

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

Will manual finish split/merge introduce side effects?

Copy link
Member Author

Choose a reason for hiding this comment

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

change the finish commands to the hidden commands

r := &cobra.Command{
Use: "finish-split <keyspace_group_id>",
Short: "finish split the keyspace group with the given ID",
Run: finishSplitKeyspaceGroupCommandFunc,
}
return r
}

func newMergeKeyspaceGroupCommand() *cobra.Command {
r := &cobra.Command{
Use: "merge <target_keyspace_group_id> [<keyspace_group_id>]",
Short: "merge the keyspace group with the given IDs into the target one",
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Short: "merge the keyspace group with the given IDs into the target one",
Short: "merge the keyspace group with the given ID into the target one",

Copy link
Member Author

@rleungx rleungx Jun 26, 2023

Choose a reason for hiding this comment

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

We do support merging serval groups into one.

Run: mergeKeyspaceGroupCommandFunc,
}
return r
}

func newFinishMergeKeyspaceGroupCommand() *cobra.Command {
r := &cobra.Command{
Use: "finish-merge <keyspace_group_id>",
Short: "finish merge the keyspace group with the given ID",
Run: finishMergeKeyspaceGroupCommandFunc,
}
return r
}

func newSetNodesKeyspaceGroupCommand() *cobra.Command {
r := &cobra.Command{
Use: "set-node <keyspace_group_id> <tso_node_addr> [<tso_node_addr>...]",
Expand Down Expand Up @@ -108,6 +138,66 @@
})
}

func finishSplitKeyspaceGroupCommandFunc(cmd *cobra.Command, args []string) {
if len(args) < 1 {
cmd.Usage()
return

Check warning on line 144 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L143-L144

Added lines #L143 - L144 were not covered by tests
}
_, err := strconv.ParseUint(args[0], 10, 32)
if err != nil {
cmd.Printf("Failed to parse the keyspace group ID: %s\n", err)
return

Check warning on line 149 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L148-L149

Added lines #L148 - L149 were not covered by tests
}
_, err = doRequest(cmd, fmt.Sprintf("%s/%s/split", keyspaceGroupsPrefix, args[0]), http.MethodDelete, http.Header{})
if err != nil {
cmd.Println(err)
return
}
cmd.Println("Success!")
}

func mergeKeyspaceGroupCommandFunc(cmd *cobra.Command, args []string) {
if len(args) < 2 {
cmd.Usage()
return

Check warning on line 162 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L161-L162

Added lines #L161 - L162 were not covered by tests
}
_, err := strconv.ParseUint(args[0], 10, 32)
if err != nil {
cmd.Printf("Failed to parse the target keyspace group ID: %s\n", err)
return

Check warning on line 167 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L166-L167

Added lines #L166 - L167 were not covered by tests
}
groups := make([]uint32, 0, len(args)-1)
for _, arg := range args[1:] {
id, err := strconv.ParseUint(arg, 10, 32)
if err != nil {
cmd.Printf("Failed to parse the keyspace ID: %s\n", err)
return

Check warning on line 174 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L173-L174

Added lines #L173 - L174 were not covered by tests
}
groups = append(groups, uint32(id))
}
postJSON(cmd, fmt.Sprintf("%s/%s/merge", keyspaceGroupsPrefix, args[0]), map[string]interface{}{
"merge-list": groups,
})
}

func finishMergeKeyspaceGroupCommandFunc(cmd *cobra.Command, args []string) {
if len(args) < 1 {
cmd.Usage()
return

Check warning on line 186 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L185-L186

Added lines #L185 - L186 were not covered by tests
}
_, err := strconv.ParseUint(args[0], 10, 32)
if err != nil {
cmd.Printf("Failed to parse the keyspace group ID: %s\n", err)
return

Check warning on line 191 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L190-L191

Added lines #L190 - L191 were not covered by tests
}
_, err = doRequest(cmd, fmt.Sprintf("%s/%s/merge", keyspaceGroupsPrefix, args[0]), http.MethodDelete, http.Header{})
if err != nil {
cmd.Println(err)
return

Check warning on line 196 in tools/pd-ctl/pdctl/command/keyspace_group_command.go

View check run for this annotation

Codecov / codecov/patch

tools/pd-ctl/pdctl/command/keyspace_group_command.go#L195-L196

Added lines #L195 - L196 were not covered by tests
}
cmd.Println("Success!")
}

func setNodesKeyspaceGroupCommandFunc(cmd *cobra.Command, args []string) {
if len(args) < 2 {
cmd.Usage()
Expand Down