Merge pull request #5290 from lyonlai/ylai-20191010-multi-split-diff-in-workflow

MultiSplitDiff support in workflow
This commit is contained in:
Andres Taylor 2019-10-11 11:59:23 +02:00 коммит произвёл GitHub
Родитель b4992f4207 37c586eadd
Коммит 0ecab461b1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 215 добавлений и 90 удалений

Просмотреть файл

@ -41,10 +41,17 @@ func createTaskID(phase workflow.PhaseType, shardName string) string {
func (hw *horizontalReshardingWorkflow) GetTasks(phase workflow.PhaseType) []*workflowpb.Task { func (hw *horizontalReshardingWorkflow) GetTasks(phase workflow.PhaseType) []*workflowpb.Task {
var shards []string var shards []string
switch phase { switch phase {
case phaseCopySchema, phaseWaitForFilteredReplication, phaseDiff: case phaseCopySchema, phaseWaitForFilteredReplication:
shards = strings.Split(hw.checkpoint.Settings["destination_shards"], ",") shards = strings.Split(hw.checkpoint.Settings["destination_shards"], ",")
case phaseClone, phaseMigrateRdonly, phaseMigrateReplica, phaseMigrateMaster: case phaseClone, phaseMigrateRdonly, phaseMigrateReplica, phaseMigrateMaster:
shards = strings.Split(hw.checkpoint.Settings["source_shards"], ",") shards = strings.Split(hw.checkpoint.Settings["source_shards"], ",")
case phaseDiff:
switch hw.checkpoint.Settings["split_diff_cmd"] {
case "SplitDiff":
shards = strings.Split(hw.checkpoint.Settings["destination_shards"], ",")
case "MultiSplitDiff":
shards = strings.Split(hw.checkpoint.Settings["source_shards"], ",")
}
default: default:
log.Fatalf("BUG: unknown phase type: %v", phase) log.Fatalf("BUG: unknown phase type: %v", phase)
} }
@ -82,15 +89,17 @@ func (hw *horizontalReshardingWorkflow) runSplitClone(ctx context.Context, t *wo
return err return err
} }
args := []string{splitCmd, "--min_healthy_rdonly_tablets=" + minHealthyRdonlyTablets, sourceKeyspaceShard} args := []string{splitCmd, "--min_healthy_rdonly_tablets=" + minHealthyRdonlyTablets}
if useConsistentSnapshot != "" { if useConsistentSnapshot != "" {
args = append(args, "--use_consistent_snapshot") args = append(args, "--use_consistent_snapshot")
} }
if excludeTables != "" { if excludeTables != "" {
args = append(args, "--exclude_tables="+excludeTables) args = append(args, fmt.Sprintf("--exclude_tables=%s", excludeTables))
} }
args = append(args, sourceKeyspaceShard)
_, err := automation.ExecuteVtworker(hw.ctx, worker, args) _, err := automation.ExecuteVtworker(hw.ctx, worker, args)
return err return err
} }
@ -103,7 +112,9 @@ func (hw *horizontalReshardingWorkflow) runWaitForFilteredReplication(ctx contex
func (hw *horizontalReshardingWorkflow) runSplitDiff(ctx context.Context, t *workflowpb.Task) error { func (hw *horizontalReshardingWorkflow) runSplitDiff(ctx context.Context, t *workflowpb.Task) error {
keyspace := t.Attributes["keyspace"] keyspace := t.Attributes["keyspace"]
splitDiffCmd := t.Attributes["split_diff_cmd"]
destShard := t.Attributes["destination_shard"] destShard := t.Attributes["destination_shard"]
sourceShard := t.Attributes["source_shard"]
destinationTabletType := t.Attributes["dest_tablet_type"] destinationTabletType := t.Attributes["dest_tablet_type"]
worker := t.Attributes["vtworker"] worker := t.Attributes["vtworker"]
useConsistentSnapshot := t.Attributes["use_consistent_snapshot"] useConsistentSnapshot := t.Attributes["use_consistent_snapshot"]
@ -112,13 +123,21 @@ func (hw *horizontalReshardingWorkflow) runSplitDiff(ctx context.Context, t *wor
if _, err := automation.ExecuteVtworker(hw.ctx, worker, []string{"Reset"}); err != nil { if _, err := automation.ExecuteVtworker(hw.ctx, worker, []string{"Reset"}); err != nil {
return err return err
} }
args := []string{"SplitDiff", "--min_healthy_rdonly_tablets=1", "--dest_tablet_type=" + destinationTabletType, topoproto.KeyspaceShardString(keyspace, destShard)} args := []string{splitDiffCmd}
if useConsistentSnapshot != "" { if useConsistentSnapshot != "" {
args = append(args, "--use_consistent_snapshot") args = append(args, "--use_consistent_snapshot")
} }
if excludeTables != "" { if excludeTables != "" {
args = append(args, "--exclude_tables="+excludeTables) args = append(args, fmt.Sprintf("--exclude_tables=%s", excludeTables))
}
switch splitDiffCmd {
case "SplitDiff":
args = append(args, "--min_healthy_rdonly_tablets=1", "--dest_tablet_type="+destinationTabletType, topoproto.KeyspaceShardString(keyspace, destShard))
case "MultiSplitDiff":
args = append(args, "--min_healthy_tablets=1", "--tablet_type="+destinationTabletType, topoproto.KeyspaceShardString(keyspace, sourceShard))
} }
_, err := automation.ExecuteVtworker(ctx, worker, args) _, err := automation.ExecuteVtworker(ctx, worker, args)

Просмотреть файл

@ -72,7 +72,9 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string)
sourceShardsStr := subFlags.String("source_shards", "", "A comma-separated list of source shards") sourceShardsStr := subFlags.String("source_shards", "", "A comma-separated list of source shards")
destinationShardsStr := subFlags.String("destination_shards", "", "A comma-separated list of destination shards") destinationShardsStr := subFlags.String("destination_shards", "", "A comma-separated list of destination shards")
minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards") minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards")
skipSplitRatioCheck := subFlags.Bool("skip_split_ratio_check", false, "Skip validation on minimum number of healthy RDONLY tablets")
splitCmd := subFlags.String("split_cmd", "SplitClone", "Split command to use to perform horizontal resharding (either SplitClone or LegacySplitClone)") splitCmd := subFlags.String("split_cmd", "SplitClone", "Split command to use to perform horizontal resharding (either SplitClone or LegacySplitClone)")
splitDiffCmd := subFlags.String("split_diff_cmd", "SplitDiff", "Split diff command to use to perform horizontal resharding (either SplitDiff or MultiSplitDiff)")
splitDiffDestTabletType := subFlags.String("split_diff_dest_tablet_type", "RDONLY", "Specifies tablet type to use in destination shards while performing SplitDiff operation") splitDiffDestTabletType := subFlags.String("split_diff_dest_tablet_type", "RDONLY", "Specifies tablet type to use in destination shards while performing SplitDiff operation")
phaseEnaableApprovalsDesc := fmt.Sprintf("Comma separated phases that require explicit approval in the UI to execute. Phase names are: %v", strings.Join(WorkflowPhases(), ",")) phaseEnaableApprovalsDesc := fmt.Sprintf("Comma separated phases that require explicit approval in the UI to execute. Phase names are: %v", strings.Join(WorkflowPhases(), ","))
phaseEnableApprovalsStr := subFlags.String("phase_enable_approvals", strings.Join(WorkflowPhases(), ","), phaseEnaableApprovalsDesc) phaseEnableApprovalsStr := subFlags.String("phase_enable_approvals", strings.Join(WorkflowPhases(), ","), phaseEnaableApprovalsDesc)
@ -81,7 +83,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string)
if err := subFlags.Parse(args); err != nil { if err := subFlags.Parse(args); err != nil {
return err return err
} }
if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" { if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" || *splitDiffCmd == "" {
return fmt.Errorf("keyspace name, min healthy rdonly tablets, split command, and vtworkers information must be provided for horizontal resharding") return fmt.Errorf("keyspace name, min healthy rdonly tablets, split command, and vtworkers information must be provided for horizontal resharding")
} }
@ -106,13 +108,13 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string)
useConsistentSnapshotArg = "true" useConsistentSnapshotArg = "true"
} }
err := validateWorkflow(m, *keyspace, vtworkers, sourceShards, destinationShards, *minHealthyRdonlyTablets) err := validateWorkflow(m, *keyspace, vtworkers, sourceShards, destinationShards, *minHealthyRdonlyTablets, *skipSplitRatioCheck)
if err != nil { if err != nil {
return err return err
} }
w.Name = fmt.Sprintf("Reshard shards %v into shards %v of keyspace %v.", *keyspace, *sourceShardsStr, *destinationShardsStr) w.Name = fmt.Sprintf("Reshard shards %v into shards %v of keyspace %v.", *keyspace, *sourceShardsStr, *destinationShardsStr)
checkpoint, err := initCheckpoint(*keyspace, vtworkers, excludeTables, sourceShards, destinationShards, *minHealthyRdonlyTablets, *splitCmd, *splitDiffDestTabletType, useConsistentSnapshotArg) checkpoint, err := initCheckpoint(*keyspace, vtworkers, excludeTables, sourceShards, destinationShards, *minHealthyRdonlyTablets, *splitCmd, *splitDiffCmd, *splitDiffDestTabletType, useConsistentSnapshotArg)
if err != nil { if err != nil {
return err return err
} }
@ -161,10 +163,12 @@ func (*Factory) Instantiate(m *workflow.Manager, w *workflowpb.Workflow, rootNod
Name: "WaitForFilteredReplication", Name: "WaitForFilteredReplication",
PathName: string(phaseWaitForFilteredReplication), PathName: string(phaseWaitForFilteredReplication),
} }
diffUINode := &workflow.Node{ diffUINode := &workflow.Node{
Name: "SplitDiff", Name: checkpoint.Settings["split_diff_cmd"],
PathName: string(phaseDiff), PathName: string(phaseDiff),
} }
migrateRdonlyUINode := &workflow.Node{ migrateRdonlyUINode := &workflow.Node{
Name: "MigrateServedTypeRDONLY", Name: "MigrateServedTypeRDONLY",
PathName: string(phaseMigrateRdonly), PathName: string(phaseMigrateRdonly),
@ -200,9 +204,19 @@ func (*Factory) Instantiate(m *workflow.Manager, w *workflowpb.Workflow, rootNod
if err := createUINodes(hw.rootUINode, phaseWaitForFilteredReplication, destinationShards); err != nil { if err := createUINodes(hw.rootUINode, phaseWaitForFilteredReplication, destinationShards); err != nil {
return hw, err return hw, err
} }
if err := createUINodes(hw.rootUINode, phaseDiff, destinationShards); err != nil { var shardsToUseForDiff []string
switch hw.checkpoint.Settings["split_diff_cmd"] {
case "SplitDiff":
shardsToUseForDiff = destinationShards
case "MultiSplitDiff":
shardsToUseForDiff = sourceShards
}
if err := createUINodes(hw.rootUINode, phaseDiff, shardsToUseForDiff); err != nil {
return hw, err return hw, err
} }
if err := createUINodes(hw.rootUINode, phaseMigrateRdonly, sourceShards); err != nil { if err := createUINodes(hw.rootUINode, phaseMigrateRdonly, sourceShards); err != nil {
return hw, err return hw, err
} }
@ -233,7 +247,7 @@ func createUINodes(rootNode *workflow.Node, phaseName workflow.PhaseType, shards
} }
// validateWorkflow validates that workflow has valid input parameters. // validateWorkflow validates that workflow has valid input parameters.
func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceShards, destinationShards []string, minHealthyRdonlyTablets string) error { func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceShards, destinationShards []string, minHealthyRdonlyTablets string, skipSplitRatioCheck bool) error {
if len(sourceShards) == 0 || len(destinationShards) == 0 { if len(sourceShards) == 0 || len(destinationShards) == 0 {
return fmt.Errorf("invalid source or destination shards") return fmt.Errorf("invalid source or destination shards")
} }
@ -242,7 +256,7 @@ func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceSha
} }
splitRatio := len(destinationShards) / len(sourceShards) splitRatio := len(destinationShards) / len(sourceShards)
if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || minHealthyRdonlyTabletsVal < splitRatio { if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || (!skipSplitRatioCheck && minHealthyRdonlyTabletsVal < splitRatio) {
return fmt.Errorf("there are not enough rdonly tablets in source shards. You need at least %v, it got: %v", splitRatio, minHealthyRdonlyTablets) return fmt.Errorf("there are not enough rdonly tablets in source shards. You need at least %v, it got: %v", splitRatio, minHealthyRdonlyTablets)
} }
@ -271,7 +285,7 @@ func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceSha
} }
// initCheckpoint initialize the checkpoint for the horizontal workflow. // initCheckpoint initialize the checkpoint for the horizontal workflow.
func initCheckpoint(keyspace string, vtworkers, excludeTables, sourceShards, destinationShards []string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType string, useConsistentSnapshot string) (*workflowpb.WorkflowCheckpoint, error) { func initCheckpoint(keyspace string, vtworkers, excludeTables, sourceShards, destinationShards []string, minHealthyRdonlyTablets, splitCmd, splitDiffCmd, splitDiffDestTabletType string, useConsistentSnapshot string) (*workflowpb.WorkflowCheckpoint, error) {
tasks := make(map[string]*workflowpb.Task) tasks := make(map[string]*workflowpb.Task)
initTasks(tasks, phaseCopySchema, destinationShards, func(i int, shard string) map[string]string { initTasks(tasks, phaseCopySchema, destinationShards, func(i int, shard string) map[string]string {
return map[string]string{ return map[string]string{
@ -298,16 +312,34 @@ func initCheckpoint(keyspace string, vtworkers, excludeTables, sourceShards, des
"destination_shard": shard, "destination_shard": shard,
} }
}) })
initTasks(tasks, phaseDiff, destinationShards, func(i int, shard string) map[string]string {
return map[string]string{ switch splitDiffCmd {
"keyspace": keyspace, case "SplitDiff":
"destination_shard": shard, initTasks(tasks, phaseDiff, destinationShards, func(i int, shard string) map[string]string {
"dest_tablet_type": splitDiffDestTabletType, return map[string]string{
"vtworker": vtworkers[i], "keyspace": keyspace,
"use_consistent_snapshot": useConsistentSnapshot, "destination_shard": shard,
"exclude_tables": strings.Join(excludeTables, ","), "dest_tablet_type": splitDiffDestTabletType,
} "split_diff_cmd": splitDiffCmd,
}) "vtworker": vtworkers[i],
"use_consistent_snapshot": useConsistentSnapshot,
"exclude_tables": strings.Join(excludeTables, ","),
}
})
case "MultiSplitDiff":
initTasks(tasks, phaseDiff, sourceShards, func(i int, shard string) map[string]string {
return map[string]string{
"keyspace": keyspace,
"source_shard": shard,
"dest_tablet_type": splitDiffDestTabletType,
"split_diff_cmd": splitDiffCmd,
"vtworker": vtworkers[i],
"use_consistent_snapshot": useConsistentSnapshot,
"exclude_tables": strings.Join(excludeTables, ","),
}
})
}
initTasks(tasks, phaseMigrateRdonly, sourceShards, func(i int, shard string) map[string]string { initTasks(tasks, phaseMigrateRdonly, sourceShards, func(i int, shard string) map[string]string {
return map[string]string{ return map[string]string{
"keyspace": keyspace, "keyspace": keyspace,
@ -336,6 +368,7 @@ func initCheckpoint(keyspace string, vtworkers, excludeTables, sourceShards, des
Settings: map[string]string{ Settings: map[string]string{
"source_shards": strings.Join(sourceShards, ","), "source_shards": strings.Join(sourceShards, ","),
"destination_shards": strings.Join(destinationShards, ","), "destination_shards": strings.Join(destinationShards, ","),
"split_diff_cmd": splitDiffCmd,
}, },
}, nil }, nil
} }

Просмотреть файл

@ -55,7 +55,7 @@ func TestSourceDestShards(t *testing.T) {
defer ctrl.Finish() defer ctrl.Finish()
// Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase. // Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase.
fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, false, "") fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, false, "", "SplitDiff")
vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory) vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory)
defer vtworkerclient.UnregisterFactoryForTest("fake") defer vtworkerclient.UnregisterFactoryForTest("fake")
@ -90,20 +90,24 @@ func TestSourceDestShards(t *testing.T) {
// TestHorizontalResharding runs the happy path of HorizontalReshardingWorkflow. // TestHorizontalResharding runs the happy path of HorizontalReshardingWorkflow.
func TestHorizontalResharding(t *testing.T) { func TestHorizontalResharding(t *testing.T) {
testHorizontalReshardingWorkflow(t, false, "") testHorizontalReshardingWorkflow(t, false, "", "SplitDiff")
} }
// TestHorizontalReshardingWithConsistentSnapshot runs the happy path of HorizontalReshardingWorkflow with consistent snapshot. // TestHorizontalReshardingWithConsistentSnapshot runs the happy path of HorizontalReshardingWorkflow with consistent snapshot.
func TestHorizontalReshardingWithConsistentSnapshot(t *testing.T) { func TestHorizontalReshardingWithConsistentSnapshot(t *testing.T) {
testHorizontalReshardingWorkflow(t, true, "") testHorizontalReshardingWorkflow(t, true, "", "SplitDiff")
} }
// TestHorizontalReshardingWithExcludedTables runs the happy path of HorizontalReshardingWorkflow with excluded tables. // TestHorizontalReshardingWithExcludedTables runs the happy path of HorizontalReshardingWorkflow with excluded tables.
func TestHorizontalReshardingWithExcludedTables(t *testing.T) { func TestHorizontalReshardingWithExcludedTables(t *testing.T) {
testHorizontalReshardingWorkflow(t, true, "table_a,table_b") testHorizontalReshardingWorkflow(t, true, "table_a,table_b", "SplitDiff")
} }
func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool, excludeTables string) { func TestHorizontalReshardingWithMultiDiffCommand(t *testing.T) {
testHorizontalReshardingWorkflow(t, true, "table_a,table_b", "MultiSplitDiff")
}
func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool, excludeTables, splitDiffCommand string) {
ctx := context.Background() ctx := context.Background()
// Set up the mock wrangler. It is used for the CopySchema, // Set up the mock wrangler. It is used for the CopySchema,
// WaitforFilteredReplication and Migrate phase. // WaitforFilteredReplication and Migrate phase.
@ -111,7 +115,7 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool,
defer ctrl.Finish() defer ctrl.Finish()
mockWranglerInterface := setupMockWrangler(ctrl, testKeyspace) mockWranglerInterface := setupMockWrangler(ctrl, testKeyspace)
// Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase. // Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase.
fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, useConsistentSnapshot, excludeTables) fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, useConsistentSnapshot, excludeTables, splitDiffCommand)
vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory) vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory)
defer vtworkerclient.UnregisterFactoryForTest("fake") defer vtworkerclient.UnregisterFactoryForTest("fake")
// Initialize the topology. // Initialize the topology.
@ -121,13 +125,14 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool,
wg, _, cancel := workflow.StartManager(m) wg, _, cancel := workflow.StartManager(m)
// Create the workflow. // Create the workflow.
vtworkersParameter := testVtworkers + "," + testVtworkers vtworkersParameter := testVtworkers + "," + testVtworkers
args := []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-phase_enable_approvals=", "-min_healthy_rdonly_tablets=2", "-source_shards=0", "-destination_shards=-80,80-"} args := []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-phase_enable_approvals=", "-min_healthy_rdonly_tablets=2"}
if useConsistentSnapshot { if useConsistentSnapshot {
args = append(args, "-use_consistent_snapshot") args = append(args, "-use_consistent_snapshot")
} }
if excludeTables != "" { if excludeTables != "" {
args = append(args, "-exclude_tables="+excludeTables) args = append(args, "-exclude_tables="+excludeTables)
} }
args = append(args, "-source_shards=0", "-destination_shards=-80,80-", "-split_diff_cmd="+splitDiffCommand)
uuid, err := m.Create(ctx, horizontalReshardingFactoryName, args) uuid, err := m.Create(ctx, horizontalReshardingFactoryName, args)
if err != nil { if err != nil {
t.Fatalf("cannot create resharding workflow: %v", err) t.Fatalf("cannot create resharding workflow: %v", err)
@ -156,15 +161,22 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool,
wg.Wait() wg.Wait()
} }
func setupFakeVtworker(keyspace, vtworkers string, useConsistentSnapshot bool, excludeTables string) *fakevtworkerclient.FakeVtworkerClient { func setupFakeVtworker(keyspace, vtworkers string, useConsistentSnapshot bool, excludeTables, splitDiffCmd string) *fakevtworkerclient.FakeVtworkerClient {
flag.Set("vtworker_client_protocol", "fake") flag.Set("vtworker_client_protocol", "fake")
fakeVtworkerClient := fakevtworkerclient.NewFakeVtworkerClient() fakeVtworkerClient := fakevtworkerclient.NewFakeVtworkerClient()
fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil)
fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitCloneCommand(keyspace, useConsistentSnapshot, excludeTables), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitCloneCommand(keyspace, useConsistentSnapshot, excludeTables), "", nil)
fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil)
fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "-80", useConsistentSnapshot, excludeTables), "", nil)
fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil)
fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "80-", useConsistentSnapshot, excludeTables), "", nil)
switch splitDiffCmd {
case "SplitDiff":
fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "-80", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil)
fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "80-", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil)
case "MultiSplitDiff":
fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "0", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil)
fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "0", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil)
}
return fakeVtworkerClient return fakeVtworkerClient
} }
@ -173,24 +185,34 @@ func resetCommand() []string {
} }
func splitCloneCommand(keyspace string, useConsistentSnapshot bool, excludeTables string) []string { func splitCloneCommand(keyspace string, useConsistentSnapshot bool, excludeTables string) []string {
args := []string{"SplitClone", "--min_healthy_rdonly_tablets=2", keyspace + "/0"} args := []string{"SplitClone", "--min_healthy_rdonly_tablets=2"}
if useConsistentSnapshot { if useConsistentSnapshot {
args = append(args, "--use_consistent_snapshot") args = append(args, "--use_consistent_snapshot")
} }
if excludeTables != "" { if excludeTables != "" {
args = append(args, "--exclude_tables="+excludeTables) args = append(args, "--exclude_tables="+excludeTables)
} }
args = append(args, keyspace+"/0")
return args return args
} }
func splitDiffCommand(keyspace string, shardId string, useConsistentSnapshot bool, excludeTables string) []string { func splitDiffCommand(keyspace string, shardId string, useConsistentSnapshot bool, excludeTables, splitDiffCommand string) []string {
args := []string{"SplitDiff", "--min_healthy_rdonly_tablets=1", "--dest_tablet_type=RDONLY", keyspace + "/" + shardId} args := []string{splitDiffCommand}
if useConsistentSnapshot { if useConsistentSnapshot {
args = append(args, "--use_consistent_snapshot") args = append(args, "--use_consistent_snapshot")
} }
if excludeTables != "" { if excludeTables != "" {
args = append(args, "--exclude_tables="+excludeTables) args = append(args, "--exclude_tables="+excludeTables)
} }
switch splitDiffCommand {
case "SplitDiff":
args = append(args, "--min_healthy_rdonly_tablets=1", "--dest_tablet_type=RDONLY", keyspace+"/"+shardId)
case "MultiSplitDiff":
args = append(args, "--min_healthy_tablets=1", "--tablet_type=RDONLY", keyspace+"/"+shardId)
}
return args return args
} }

Просмотреть файл

@ -60,7 +60,9 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string)
vtworkersStr := subFlags.String("vtworkers", "", "A comma-separated list of vtworker addresses") vtworkersStr := subFlags.String("vtworkers", "", "A comma-separated list of vtworker addresses")
excludeTablesStr := subFlags.String("exclude_tables", "", "A comma-separated list of tables to exclude") excludeTablesStr := subFlags.String("exclude_tables", "", "A comma-separated list of tables to exclude")
minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards") minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards")
skipSplitRatioCheck := subFlags.Bool("skip_split_ratio_check", false, "Skip validation on minimum number of healthy RDONLY tablets")
splitCmd := subFlags.String("split_cmd", "SplitClone", "Split command to use to perform horizontal resharding (either SplitClone or LegacySplitClone)") splitCmd := subFlags.String("split_cmd", "SplitClone", "Split command to use to perform horizontal resharding (either SplitClone or LegacySplitClone)")
splitDiffCmd := subFlags.String("split_diff_cmd", "SplitDiff", "Split diff command to use to perform horizontal resharding (either SplitDiff or MultiSplitDiff)")
splitDiffDestTabletType := subFlags.String("split_diff_dest_tablet_type", "RDONLY", "Specifies tablet type to use in destination shards while performing SplitDiff operation") splitDiffDestTabletType := subFlags.String("split_diff_dest_tablet_type", "RDONLY", "Specifies tablet type to use in destination shards while performing SplitDiff operation")
skipStartWorkflows := subFlags.Bool("skip_start_workflows", true, "If true, newly created workflows will have skip_start set") skipStartWorkflows := subFlags.Bool("skip_start_workflows", true, "If true, newly created workflows will have skip_start set")
phaseEnableApprovalsDesc := fmt.Sprintf("Comma separated phases that require explicit approval in the UI to execute. Phase names are: %v", strings.Join(resharding.WorkflowPhases(), ",")) phaseEnableApprovalsDesc := fmt.Sprintf("Comma separated phases that require explicit approval in the UI to execute. Phase names are: %v", strings.Join(resharding.WorkflowPhases(), ","))
@ -70,7 +72,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string)
if err := subFlags.Parse(args); err != nil { if err := subFlags.Parse(args); err != nil {
return err return err
} }
if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" { if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" || *splitDiffCmd == "" {
return fmt.Errorf("keyspace name, min healthy rdonly tablets, split command, and vtworkers information must be provided for horizontal resharding") return fmt.Errorf("keyspace name, min healthy rdonly tablets, split command, and vtworkers information must be provided for horizontal resharding")
} }
@ -90,10 +92,12 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string)
shardsToSplit, shardsToSplit,
*minHealthyRdonlyTablets, *minHealthyRdonlyTablets,
*splitCmd, *splitCmd,
*splitDiffCmd,
*splitDiffDestTabletType, *splitDiffDestTabletType,
*phaseEnableApprovalsStr, *phaseEnableApprovalsStr,
*skipStartWorkflows, *skipStartWorkflows,
*useConsistentSnapshot, *useConsistentSnapshot,
*skipSplitRatioCheck,
) )
if err != nil { if err != nil {
return err return err
@ -132,7 +136,10 @@ func (*Factory) Instantiate(m *workflow.Manager, w *workflowpb.Workflow, rootNod
keyspaceParam: checkpoint.Settings["keyspace"], keyspaceParam: checkpoint.Settings["keyspace"],
splitDiffDestTabletTypeParam: checkpoint.Settings["split_diff_dest_tablet_type"], splitDiffDestTabletTypeParam: checkpoint.Settings["split_diff_dest_tablet_type"],
splitCmdParam: checkpoint.Settings["split_cmd"], splitCmdParam: checkpoint.Settings["split_cmd"],
splitDiffCmdParam: checkpoint.Settings["split_diff_cmd"],
useConsistentSnapshot: checkpoint.Settings["use_consistent_snapshot"], useConsistentSnapshot: checkpoint.Settings["use_consistent_snapshot"],
excludeTablesParam: checkpoint.Settings["exclude_tables"],
skipSplitRatioCheckParam: checkpoint.Settings["skip_split_ratio_check"],
workflowsCount: workflowsCount, workflowsCount: workflowsCount,
} }
createWorkflowsUINode := &workflow.Node{ createWorkflowsUINode := &workflow.Node{
@ -194,7 +201,7 @@ func findSourceAndDestinationShards(ts *topo.Server, keyspace string) ([][][]str
} }
// initCheckpoint initialize the checkpoint for keyspace reshard // initCheckpoint initialize the checkpoint for keyspace reshard
func initCheckpoint(keyspace string, vtworkers, excludeTables []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows bool, useConsistentSnapshot bool) (*workflowpb.WorkflowCheckpoint, error) { func initCheckpoint(keyspace string, vtworkers, excludeTables []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows, useConsistentSnapshot, skipSplitRatioCheck bool) (*workflowpb.WorkflowCheckpoint, error) {
sourceShards := 0 sourceShards := 0
destShards := 0 destShards := 0
for _, shardToSplit := range shardsToSplit { for _, shardToSplit := range shardsToSplit {
@ -209,7 +216,7 @@ func initCheckpoint(keyspace string, vtworkers, excludeTables []string, shardsTo
} }
splitRatio := destShards / sourceShards splitRatio := destShards / sourceShards
if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || minHealthyRdonlyTabletsVal < splitRatio { if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || (!skipSplitRatioCheck && minHealthyRdonlyTabletsVal < splitRatio) {
return nil, fmt.Errorf("there are not enough rdonly tablets in source shards. You need at least %v, it got: %v", splitRatio, minHealthyRdonlyTablets) return nil, fmt.Errorf("there are not enough rdonly tablets in source shards. You need at least %v, it got: %v", splitRatio, minHealthyRdonlyTablets)
} }
@ -235,13 +242,15 @@ func initCheckpoint(keyspace string, vtworkers, excludeTables []string, shardsTo
"vtworkers": strings.Join(vtworkers, ","), "vtworkers": strings.Join(vtworkers, ","),
"min_healthy_rdonly_tablets": minHealthyRdonlyTablets, "min_healthy_rdonly_tablets": minHealthyRdonlyTablets,
"split_cmd": splitCmd, "split_cmd": splitCmd,
"split_diff_cmd": splitDiffCmd,
"split_diff_dest_tablet_type": splitDiffDestTabletType, "split_diff_dest_tablet_type": splitDiffDestTabletType,
"phase_enable_approvals": phaseEnableApprovals, "phase_enable_approvals": phaseEnableApprovals,
"skip_start_workflows": fmt.Sprintf("%v", skipStartWorkflows), "skip_start_workflows": fmt.Sprintf("%v", skipStartWorkflows),
"workflows_count": fmt.Sprintf("%v", len(shardsToSplit)), "workflows_count": fmt.Sprintf("%v", len(shardsToSplit)),
"keyspace": keyspace, "keyspace": keyspace,
"use_consistent_snapshot": fmt.Sprintf("%v", useConsistentSnapshot), "use_consistent_snapshot": fmt.Sprintf("%v", useConsistentSnapshot),
"exclude_tables": fmt.Sprintf("%v", strings.Join(excludeTables, ",")), "exclude_tables": strings.Join(excludeTables, ","),
"skip_split_ratio_check": fmt.Sprintf("%v", skipSplitRatioCheck),
}, },
}, nil }, nil
} }
@ -270,8 +279,11 @@ type reshardingWorkflowGen struct {
keyspaceParam string keyspaceParam string
splitDiffDestTabletTypeParam string splitDiffDestTabletTypeParam string
splitCmdParam string splitCmdParam string
splitDiffCmdParam string
skipStartWorkflowParam string skipStartWorkflowParam string
useConsistentSnapshot string useConsistentSnapshot string
excludeTablesParam string
skipSplitRatioCheckParam string
} }
// Run implements workflow.Workflow interface. It creates one horizontal resharding workflow per shard to split // Run implements workflow.Workflow interface. It creates one horizontal resharding workflow per shard to split
@ -305,8 +317,10 @@ func (hw *reshardingWorkflowGen) workflowCreator(ctx context.Context, task *work
horizontalReshardingParams := []string{ horizontalReshardingParams := []string{
"-keyspace=" + hw.keyspaceParam, "-keyspace=" + hw.keyspaceParam,
"-vtworkers=" + task.Attributes["vtworkers"], "-vtworkers=" + task.Attributes["vtworkers"],
"-exclude_tables=" + task.Attributes["exclude_tables"], "-exclude_tables=" + hw.excludeTablesParam,
"-skip_split_ratio_check=" + hw.skipSplitRatioCheckParam,
"-split_cmd=" + hw.splitCmdParam, "-split_cmd=" + hw.splitCmdParam,
"-split_diff_cmd=" + hw.splitDiffCmdParam,
"-split_diff_dest_tablet_type=" + hw.splitDiffDestTabletTypeParam, "-split_diff_dest_tablet_type=" + hw.splitDiffDestTabletTypeParam,
"-min_healthy_rdonly_tablets=" + hw.minHealthyRdonlyTabletsParam, "-min_healthy_rdonly_tablets=" + hw.minHealthyRdonlyTabletsParam,
"-source_shards=" + task.Attributes["source_shards"], "-source_shards=" + task.Attributes["source_shards"],

Просмотреть файл

@ -27,5 +27,5 @@
</head> </head>
<body class="flex-column"> <body class="flex-column">
<vt-app-root class="flex-column flex-grow">Loading...</vt-app-root> <vt-app-root class="flex-column flex-grow">Loading...</vt-app-root>
<script type="text/javascript" src="inline.js"></script><script type="text/javascript" src="styles.38b88af69dfd283498eb.bundle.js"></script><script type="text/javascript" src="main.38a1a560f8f628e31552.bundle.js"></script></body> <script type="text/javascript" src="inline.js"></script><script type="text/javascript" src="styles.38b88af69dfd283498eb.bundle.js"></script><script type="text/javascript" src="main.3a2141f06032f2bc1229.bundle.js"></script></body>
</html> </html>

Просмотреть файл

@ -1 +1 @@
!function(e){function __webpack_require__(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,__webpack_require__),n.l=!0,n.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,o,_){for(var c,a,i,u=0,p=[];u<t.length;u++)a=t[u],n[a]&&p.push(n[a][0]),n[a]=0;for(c in o)if(Object.prototype.hasOwnProperty.call(o,c)){var f=o[c];switch(typeof f){case"object":e[c]=function(r){var t=r.slice(1),n=r[0];return function(r,o,_){e[n].apply(this,[r,o,_].concat(t))}}(f);break;case"function":e[c]=f;break;default:e[c]=e[f]}}for(r&&r(t,o,_);p.length;)p.shift()();if(_)for(u=0;u<_.length;u++)i=__webpack_require__(__webpack_require__.s=_[u]);return i};var t={},n={2:0};__webpack_require__.e=function(e){function onScriptComplete(){t.onerror=t.onload=null,clearTimeout(o);var r=n[e];0!==r&&(r&&r[1](new Error("Loading chunk "+e+" failed.")),n[e]=void 0)}if(0===n[e])return Promise.resolve();if(n[e])return n[e][2];var r=document.getElementsByTagName("head")[0],t=document.createElement("script");t.type="text/javascript",t.charset="utf-8",t.async=!0,t.timeout=12e4,t.src=__webpack_require__.p+""+e+"."+{0:"38a1a560f8f628e31552",1:"38b88af69dfd283498eb"}[e]+".chunk.js";var o=setTimeout(onScriptComplete,12e4);t.onerror=t.onload=onScriptComplete,r.appendChild(t);var _=new Promise(function(r,t){n[e]=[r,t]});return n[e][2]=_},__webpack_require__.m=e,__webpack_require__.c=t,__webpack_require__.i=function(e){return e},__webpack_require__.d=function(e,r,t){Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},__webpack_require__.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(r,"a",r),r},__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},__webpack_require__.p="",__webpack_require__.oe=function(e){throw console.error(e),e}}(function(e){for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))switch(typeof e[r]){case"function":break;case"object":e[r]=function(r){var t=r.slice(1),n=e[r[0]];return function(e,r,o){n.apply(this,[e,r,o].concat(t))}}(e[r]);break;default:e[r]=e[e[r]]}return e}([])); !function(e){function __webpack_require__(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,__webpack_require__),n.l=!0,n.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,o,c){for(var _,a,i,u=0,p=[];u<t.length;u++)a=t[u],n[a]&&p.push(n[a][0]),n[a]=0;for(_ in o)if(Object.prototype.hasOwnProperty.call(o,_)){var f=o[_];switch(typeof f){case"object":e[_]=function(r){var t=r.slice(1),n=r[0];return function(r,o,c){e[n].apply(this,[r,o,c].concat(t))}}(f);break;case"function":e[_]=f;break;default:e[_]=e[f]}}for(r&&r(t,o,c);p.length;)p.shift()();if(c)for(u=0;u<c.length;u++)i=__webpack_require__(__webpack_require__.s=c[u]);return i};var t={},n={2:0};__webpack_require__.e=function(e){function onScriptComplete(){t.onerror=t.onload=null,clearTimeout(o);var r=n[e];0!==r&&(r&&r[1](new Error("Loading chunk "+e+" failed.")),n[e]=void 0)}if(0===n[e])return Promise.resolve();if(n[e])return n[e][2];var r=document.getElementsByTagName("head")[0],t=document.createElement("script");t.type="text/javascript",t.charset="utf-8",t.async=!0,t.timeout=12e4,t.src=__webpack_require__.p+""+e+"."+{0:"3a2141f06032f2bc1229",1:"38b88af69dfd283498eb"}[e]+".chunk.js";var o=setTimeout(onScriptComplete,12e4);t.onerror=t.onload=onScriptComplete,r.appendChild(t);var c=new Promise(function(r,t){n[e]=[r,t]});return n[e][2]=c},__webpack_require__.m=e,__webpack_require__.c=t,__webpack_require__.i=function(e){return e},__webpack_require__.d=function(e,r,t){Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},__webpack_require__.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(r,"a",r),r},__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},__webpack_require__.p="",__webpack_require__.oe=function(e){throw console.error(e),e}}(function(e){for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))switch(typeof e[r]){case"function":break;case"object":e[r]=function(r){var t=r.slice(1),n=e[r[0]];return function(e,r,o){n.apply(this,[e,r,o].concat(t))}}(e[r]);break;default:e[r]=e[e[r]]}return e}([]));

Двоичный файл не отображается.

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Двоичные данные
web/vtctld2/app/main.3a2141f06032f2bc1229.bundle.js.gz Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -42,80 +42,92 @@ export class NewWorkflowFlags {
this.flags['horizontal_resharding_split_cmd'] = new SplitCloneCommand(10, 'horizontal_resharding_split_cmd', 'horizontal_resharding'); this.flags['horizontal_resharding_split_cmd'] = new SplitCloneCommand(10, 'horizontal_resharding_split_cmd', 'horizontal_resharding');
this.flags['horizontal_resharding_split_cmd'].positional = true; this.flags['horizontal_resharding_split_cmd'].positional = true;
this.flags['horizontal_resharding_split_cmd'].namedPositional = 'split_cmd'; this.flags['horizontal_resharding_split_cmd'].namedPositional = 'split_cmd';
this.flags['horizontal_resharding_split_diff_dest_tablet_type'] = new SplitDiffTabletType(11, 'horizontal_resharding_split_diff_dest_tablet_type', 'horizontal_resharding'); this.flags['horizontal_resharding_split_diff_cmd'] = new SplitDiffCommand(11, 'horizontal_resharding_split_diff_cmd', 'horizontal_resharding');
this.flags['horizontal_resharding_split_diff_cmd'].positional = true;
this.flags['horizontal_resharding_split_diff_cmd'].namedPositional = 'split_diff_cmd';
this.flags['horizontal_resharding_split_diff_dest_tablet_type'] = new SplitDiffTabletType(12, 'horizontal_resharding_split_diff_dest_tablet_type', 'horizontal_resharding');
this.flags['horizontal_resharding_split_diff_dest_tablet_type'].positional = true; this.flags['horizontal_resharding_split_diff_dest_tablet_type'].positional = true;
this.flags['horizontal_resharding_split_diff_dest_tablet_type'].namedPositional = 'split_diff_dest_tablet_type'; this.flags['horizontal_resharding_split_diff_dest_tablet_type'].namedPositional = 'split_diff_dest_tablet_type';
this.flags['horizontal_resharding_min_healthy_rdonly_tablets'] = new HorizontalReshardingMinHealthyRdonlyTablets(12, 'horizontal_resharding_min_healthy_rdonly_tablets', 'horizontal_resharding'); this.flags['horizontal_resharding_min_healthy_rdonly_tablets'] = new HorizontalReshardingMinHealthyRdonlyTablets(13, 'horizontal_resharding_min_healthy_rdonly_tablets', 'horizontal_resharding');
this.flags['horizontal_resharding_min_healthy_rdonly_tablets'].positional = true; this.flags['horizontal_resharding_min_healthy_rdonly_tablets'].positional = true;
this.flags['horizontal_resharding_min_healthy_rdonly_tablets'].namedPositional = 'min_healthy_rdonly_tablets'; this.flags['horizontal_resharding_min_healthy_rdonly_tablets'].namedPositional = 'min_healthy_rdonly_tablets';
this.flags['horizontal_resharding_use_consistent_snapshot'] = new HorizontalReshardingConsistentSnapshotFlag(13, 'horizontal_resharding_use_consistent_snapshot', 'Use Consistent Snapshot', 'horizontal_resharding'); this.flags['horizontal_resharding_skip_split_ratio_check'] = new HorizontalReshardingSkipSplitRatioCheckFlag(14, 'horizontal_resharding_skip_split_ratio_check', 'Skip Split Ratio Check', 'horizontal_resharding');
this.flags['horizontal_resharding_skip_split_ratio_check'].positional = true;
this.flags['horizontal_resharding_skip_split_ratio_check'].namedPositional = 'skip_split_ratio_check';
this.flags['horizontal_resharding_use_consistent_snapshot'] = new HorizontalReshardingConsistentSnapshotFlag(15, 'horizontal_resharding_use_consistent_snapshot', 'Use Consistent Snapshot', 'horizontal_resharding');
this.flags['horizontal_resharding_use_consistent_snapshot'].positional = true; this.flags['horizontal_resharding_use_consistent_snapshot'].positional = true;
this.flags['horizontal_resharding_use_consistent_snapshot'].namedPositional = 'use_consistent_snapshot'; this.flags['horizontal_resharding_use_consistent_snapshot'].namedPositional = 'use_consistent_snapshot';
this.flags['horizontal_resharding_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(14, 'horizontal_resharding_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(16, 'horizontal_resharding_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'horizontal_resharding');
this.flags['horizontal_resharding_enable_approvals_copy_schema'].positional = true; this.flags['horizontal_resharding_enable_approvals_copy_schema'].positional = true;
this.flags['horizontal_resharding_enable_approvals_copy_schema'].namedPositional = 'copy_schema'; this.flags['horizontal_resharding_enable_approvals_copy_schema'].namedPositional = 'copy_schema';
this.flags['horizontal_resharding_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(15, 'horizontal_resharding_enable_approvals_clone', 'Clone enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(17, 'horizontal_resharding_enable_approvals_clone', 'Clone enable approvals', 'horizontal_resharding');
this.flags['horizontal_resharding_enable_approvals_clone'].positional = true; this.flags['horizontal_resharding_enable_approvals_clone'].positional = true;
this.flags['horizontal_resharding_enable_approvals_clone'].namedPositional = 'clone'; this.flags['horizontal_resharding_enable_approvals_clone'].namedPositional = 'clone';
this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(16, 'horizontal_resharding_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(18, 'horizontal_resharding_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'horizontal_resharding');
this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'].positional = true; this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'].positional = true;
this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'].namedPositional = 'wait_for_filtered_replication'; this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'].namedPositional = 'wait_for_filtered_replication';
this.flags['horizontal_resharding_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(17, 'horizontal_resharding_enable_approvals_diff', 'Diff enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(19, 'horizontal_resharding_enable_approvals_diff', 'Diff enable approvals', 'horizontal_resharding');
this.flags['horizontal_resharding_enable_approvals_diff'].positional = true; this.flags['horizontal_resharding_enable_approvals_diff'].positional = true;
this.flags['horizontal_resharding_enable_approvals_diff'].namedPositional = 'diff'; this.flags['horizontal_resharding_enable_approvals_diff'].namedPositional = 'diff';
this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(18, 'horizontal_resharding_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(20, 'horizontal_resharding_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'horizontal_resharding');
this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'].positional = true; this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'].positional = true;
this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'].namedPositional = 'migrate_rdonly,migrate_replica,migrate_master'; this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'].namedPositional = 'migrate_rdonly,migrate_replica,migrate_master';
this.flags['horizontal_resharding_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(19, 'horizontal_resharding_phase_enable_approvals'); this.flags['horizontal_resharding_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(21, 'horizontal_resharding_phase_enable_approvals');
this.flags['horizontal_resharding_phase_enable_approvals'].positional = true; this.flags['horizontal_resharding_phase_enable_approvals'].positional = true;
this.flags['horizontal_resharding_phase_enable_approvals'].namedPositional = 'phase_enable_approvals'; this.flags['horizontal_resharding_phase_enable_approvals'].namedPositional = 'phase_enable_approvals';
// // Flags for keyspace resharding workflow. // // Flags for keyspace resharding workflow.
this.flags['hr_workflow_gen_keyspace'] = new HorizontalReshardingKeyspaceFlag(20, 'hr_workflow_gen_keyspace', 'hr_workflow_gen'); this.flags['hr_workflow_gen_keyspace'] = new HorizontalReshardingKeyspaceFlag(22, 'hr_workflow_gen_keyspace', 'hr_workflow_gen');
this.flags['hr_workflow_gen_keyspace'].positional = true; this.flags['hr_workflow_gen_keyspace'].positional = true;
this.flags['hr_workflow_gen_keyspace'].namedPositional = 'keyspace'; this.flags['hr_workflow_gen_keyspace'].namedPositional = 'keyspace';
this.flags['hr_workflow_gen_vtworkers'] = new HorizontalReshardingVtworkerFlag(21, 'hr_workflow_gen_vtworkers', 'hr_workflow_gen'); this.flags['hr_workflow_gen_vtworkers'] = new HorizontalReshardingVtworkerFlag(23, 'hr_workflow_gen_vtworkers', 'hr_workflow_gen');
this.flags['hr_workflow_gen_vtworkers'].positional = true; this.flags['hr_workflow_gen_vtworkers'].positional = true;
this.flags['hr_workflow_gen_vtworkers'].namedPositional = 'vtworkers'; this.flags['hr_workflow_gen_vtworkers'].namedPositional = 'vtworkers';
this.flags['hr_workflow_gen_exclude_tables'] = new HorizontalReshardingExcludeTablesFlag(22, 'hr_workflow_gen_exclude_tables', 'hr_workflow_gen'); this.flags['hr_workflow_gen_exclude_tables'] = new HorizontalReshardingExcludeTablesFlag(24, 'hr_workflow_gen_exclude_tables', 'hr_workflow_gen');
this.flags['hr_workflow_gen_exclude_tables'].positional = true; this.flags['hr_workflow_gen_exclude_tables'].positional = true;
this.flags['hr_workflow_gen_exclude_tables'].namedPositional = 'exclude_tables'; this.flags['hr_workflow_gen_exclude_tables'].namedPositional = 'exclude_tables';
this.flags['hr_workflow_gen_split_cmd'] = new SplitCloneCommand(23, 'hr_workflow_gen_split_cmd', 'hr_workflow_gen'); this.flags['hr_workflow_gen_split_cmd'] = new SplitCloneCommand(25, 'hr_workflow_gen_split_cmd', 'hr_workflow_gen');
this.flags['hr_workflow_gen_split_cmd'].positional = true; this.flags['hr_workflow_gen_split_cmd'].positional = true;
this.flags['hr_workflow_gen_split_cmd'].namedPositional = 'split_cmd'; this.flags['hr_workflow_gen_split_cmd'].namedPositional = 'split_cmd';
this.flags['hr_workflow_gen_split_diff_dest_tablet_type'] = new SplitDiffTabletType(24, 'hr_workflow_gen_split_diff_dest_tablet_type', 'hr_workflow_gen'); this.flags['hr_workflow_gen_split_diff_cmd'] = new SplitDiffCommand(26, 'hr_workflow_gen_split_diff_cmd', 'hr_workflow_gen');
this.flags['hr_workflow_gen_split_diff_cmd'].positional = true;
this.flags['hr_workflow_gen_split_diff_cmd'].namedPositional = 'split_diff_cmd';
this.flags['hr_workflow_gen_split_diff_dest_tablet_type'] = new SplitDiffTabletType(27, 'hr_workflow_gen_split_diff_dest_tablet_type', 'hr_workflow_gen');
this.flags['hr_workflow_gen_split_diff_dest_tablet_type'].positional = true; this.flags['hr_workflow_gen_split_diff_dest_tablet_type'].positional = true;
this.flags['hr_workflow_gen_split_diff_dest_tablet_type'].namedPositional = 'split_diff_dest_tablet_type'; this.flags['hr_workflow_gen_split_diff_dest_tablet_type'].namedPositional = 'split_diff_dest_tablet_type';
this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'] = new HorizontalReshardingMinHealthyRdonlyTablets(25, 'hr_workflow_gen_min_healthy_rdonly_tablets', 'hr_workflow_gen'); this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'] = new HorizontalReshardingMinHealthyRdonlyTablets(28, 'hr_workflow_gen_min_healthy_rdonly_tablets', 'hr_workflow_gen');
this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'].positional = true; this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'].positional = true;
this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'].namedPositional = 'min_healthy_rdonly_tablets'; this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'].namedPositional = 'min_healthy_rdonly_tablets';
this.flags['hr_workflow_gen_use_consistent_snapshot'] = new HorizontalReshardingConsistentSnapshotFlag(26, 'hr_workflow_gen_use_consistent_snapshot', 'Use Consistent Snapshot', 'hr_workflow_gen'); this.flags['hr_workflow_gen_skip_split_ratio_check'] = new HorizontalReshardingSkipSplitRatioCheckFlag(29, 'hr_workflow_gen_skip_split_ratio_check', 'Skip Split Ratio Check', 'hr_workflow_gen');
this.flags['hr_workflow_gen_skip_split_ratio_check'].positional = true;
this.flags['hr_workflow_gen_skip_split_ratio_check'].namedPositional = 'skip_split_ratio_check';
this.flags['hr_workflow_gen_use_consistent_snapshot'] = new HorizontalReshardingConsistentSnapshotFlag(30, 'hr_workflow_gen_use_consistent_snapshot', 'Use Consistent Snapshot', 'hr_workflow_gen');
this.flags['hr_workflow_gen_use_consistent_snapshot'].positional = true; this.flags['hr_workflow_gen_use_consistent_snapshot'].positional = true;
this.flags['hr_workflow_gen_use_consistent_snapshot'].namedPositional = 'use_consistent_snapshot'; this.flags['hr_workflow_gen_use_consistent_snapshot'].namedPositional = 'use_consistent_snapshot';
this.flags['hr_workflow_gen_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(27, 'hr_workflow_gen_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(31, 'hr_workflow_gen_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'hr_workflow_gen');
this.flags['hr_workflow_gen_enable_approvals_copy_schema'].positional = true; this.flags['hr_workflow_gen_enable_approvals_copy_schema'].positional = true;
this.flags['hr_workflow_gen_enable_approvals_copy_schema'].namedPositional = 'copy_schema'; this.flags['hr_workflow_gen_enable_approvals_copy_schema'].namedPositional = 'copy_schema';
this.flags['hr_workflow_gen_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(28, 'hr_workflow_gen_enable_approvals_clone', 'Clone enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(32, 'hr_workflow_gen_enable_approvals_clone', 'Clone enable approvals', 'hr_workflow_gen');
this.flags['hr_workflow_gen_enable_approvals_clone'].positional = true; this.flags['hr_workflow_gen_enable_approvals_clone'].positional = true;
this.flags['hr_workflow_gen_enable_approvals_clone'].namedPositional = 'clone'; this.flags['hr_workflow_gen_enable_approvals_clone'].namedPositional = 'clone';
this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(29, 'hr_workflow_gen_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(33, 'hr_workflow_gen_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'hr_workflow_gen');
this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'].positional = true; this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'].positional = true;
this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'].namedPositional = 'wait_for_filtered_replication'; this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'].namedPositional = 'wait_for_filtered_replication';
this.flags['hr_workflow_gen_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(30, 'hr_workflow_gen_enable_approvals_diff', 'Diff enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(34, 'hr_workflow_gen_enable_approvals_diff', 'Diff enable approvals', 'hr_workflow_gen');
this.flags['hr_workflow_gen_enable_approvals_diff'].positional = true; this.flags['hr_workflow_gen_enable_approvals_diff'].positional = true;
this.flags['hr_workflow_gen_enable_approvals_diff'].namedPositional = 'diff'; this.flags['hr_workflow_gen_enable_approvals_diff'].namedPositional = 'diff';
this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(31, 'hr_workflow_gen_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(35, 'hr_workflow_gen_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'hr_workflow_gen');
this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'].positional = true; this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'].positional = true;
this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'].namedPositional = 'migrate_rdonly,migrate_replica,migrate_master'; this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'].namedPositional = 'migrate_rdonly,migrate_replica,migrate_master';
this.flags['hr_workflow_gen_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(32, 'hr_workflow_gen_phase_enable_approvals'); this.flags['hr_workflow_gen_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(36, 'hr_workflow_gen_phase_enable_approvals');
this.flags['hr_workflow_gen_phase_enable_approvals'].positional = true; this.flags['hr_workflow_gen_phase_enable_approvals'].positional = true;
this.flags['hr_workflow_gen_phase_enable_approvals'].namedPositional = 'phase_enable_approvals'; this.flags['hr_workflow_gen_phase_enable_approvals'].namedPositional = 'phase_enable_approvals';
this.flags['hr_workflow_gen_skip_start_workflows'] = new ReshardingWorkflowGenSkipStartFlag(33, 'hr_workflow_gen_skip_start_workflows'); this.flags['hr_workflow_gen_skip_start_workflows'] = new ReshardingWorkflowGenSkipStartFlag(37, 'hr_workflow_gen_skip_start_workflows');
this.flags['hr_workflow_gen_skip_start_workflows'].positional = true; this.flags['hr_workflow_gen_skip_start_workflows'].positional = true;
this.flags['hr_workflow_gen_skip_start_workflows'].namedPositional = 'skip_start_workflows'; this.flags['hr_workflow_gen_skip_start_workflows'].namedPositional = 'skip_start_workflows';
@ -140,6 +152,24 @@ export class SplitCloneCommand extends DropDownFlag {
} }
} }
export class SplitDiffCommand extends DropDownFlag {
constructor(position: number, id: string, setDisplayOn: string) {
super(position, id, 'Split Diff Command', 'Specifies the split diff command to use.', '');
let options = [];
options.push({
label: 'SplitDiff',
value: 'SplitDiff'
});
options.push({
label: 'MultiSplitDiff',
value: 'MultiSplitDiff'
});
this.setOptions(options);
this.value = options[0].value;
this.setDisplayOn('factory_name', setDisplayOn);
}
}
export class SplitDiffTabletType extends DropDownFlag { export class SplitDiffTabletType extends DropDownFlag {
constructor(position: number, id: string, setDisplayOn: string) { constructor(position: number, id: string, setDisplayOn: string) {
super(position, id, 'SplitDiff destination tablet type', 'Specifies tablet type to use in destination shards while performing SplitDiff operation', ''); super(position, id, 'SplitDiff destination tablet type', 'Specifies tablet type to use in destination shards while performing SplitDiff operation', '');
@ -294,6 +324,13 @@ export class HorizontalReshardingConsistentSnapshotFlag extends CheckBoxFlag {
} }
} }
export class HorizontalReshardingSkipSplitRatioCheckFlag extends CheckBoxFlag {
constructor(position: number, id: string, name: string, setDisplayOn: string, value = false) {
super(position, id, name, 'Skip the validation on minimum healthy rdonly tablets', value);
this.setDisplayOn('factory_name', setDisplayOn);
}
}
// WorkflowFlags is used by the Start / Stop / Delete dialogs. // WorkflowFlags is used by the Start / Stop / Delete dialogs.
export class WorkflowFlags { export class WorkflowFlags {
flags= {}; flags= {};