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 all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"))
}
92 changes: 92 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,35 @@
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,
Hidden: true,
}
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,
Hidden: true,
}
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 +140,66 @@
})
}

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

Check warning on line 146 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#L145-L146

Added lines #L145 - L146 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 151 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#L150-L151

Added lines #L150 - L151 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 164 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#L163-L164

Added lines #L163 - L164 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 169 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#L168-L169

Added lines #L168 - L169 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 176 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#L175-L176

Added lines #L175 - L176 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 188 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#L187-L188

Added lines #L187 - L188 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 193 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#L192-L193

Added lines #L192 - L193 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 198 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#L197-L198

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

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