Skip to content

Commit c5d0ecc

Browse files
authored
Online DDL: dynamic cut-over threshold via ALTER VITESS_MIGRATION ... CUTOVER_THRESHOLD ... command (#17126)
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
1 parent fb79106 commit c5d0ecc

File tree

18 files changed

+9469
-9227
lines changed

18 files changed

+9469
-9227
lines changed

go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ func testScheduler(t *testing.T) {
484484
testTableSequentialTimes(t, t1uuid, t2uuid)
485485
})
486486
t.Run("Postpone launch CREATE", func(t *testing.T) {
487-
t1uuid = testOnlineDDLStatement(t, createParams(createT1IfNotExistsStatement, ddlStrategy+" --postpone-launch", "vtgate", "", "", true)) // skip wait
487+
t1uuid = testOnlineDDLStatement(t, createParams(createT1IfNotExistsStatement, ddlStrategy+" --postpone-launch --cut-over-threshold=14s", "vtgate", "", "", true)) // skip wait
488488
time.Sleep(2 * time.Second)
489489
rs := onlineddl.ReadMigrations(t, &vtParams, t1uuid)
490490
require.NotNil(t, rs)
@@ -501,6 +501,10 @@ func testScheduler(t *testing.T) {
501501
for _, row := range rs.Named().Rows {
502502
postponeLaunch := row.AsInt64("postpone_launch", 0)
503503
assert.Equal(t, int64(0), postponeLaunch)
504+
505+
cutOverThresholdSeconds := row.AsInt64("cutover_threshold_seconds", 0)
506+
// Threshold supplied in DDL strategy
507+
assert.EqualValues(t, 14, cutOverThresholdSeconds)
504508
}
505509
status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed)
506510
fmt.Printf("# Migration status (for debug purposes): <%s>\n", status)
@@ -580,6 +584,9 @@ func testScheduler(t *testing.T) {
580584
assert.Equal(t, int64(1), postponeCompletion)
581585
}
582586
})
587+
t.Run("set cut-over threshold", func(t *testing.T) {
588+
onlineddl.CheckSetMigrationCutOverThreshold(t, &vtParams, shards, t1uuid, 17700*time.Millisecond, "")
589+
})
583590
t.Run("complete", func(t *testing.T) {
584591
onlineddl.CheckCompleteMigration(t, &vtParams, shards, t1uuid, true)
585592
status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed)
@@ -592,6 +599,11 @@ func testScheduler(t *testing.T) {
592599
for _, row := range rs.Named().Rows {
593600
postponeCompletion := row.AsInt64("postpone_completion", 0)
594601
assert.Equal(t, int64(0), postponeCompletion)
602+
603+
cutOverThresholdSeconds := row.AsInt64("cutover_threshold_seconds", 0)
604+
// Expect 17800*time.Millisecond to be truncated to 17 seconds
605+
assert.EqualValues(t, 17, cutOverThresholdSeconds)
606+
595607
assert.False(t, row["shadow_analyzed_timestamp"].IsNull())
596608
}
597609
})
@@ -1062,6 +1074,10 @@ func testScheduler(t *testing.T) {
10621074
for _, row := range rs.Named().Rows {
10631075
retries := row.AsInt64("retries", 0)
10641076
assert.Greater(t, retries, int64(0))
1077+
1078+
cutOverThresholdSeconds := row.AsInt64("cutover_threshold_seconds", 0)
1079+
// No explicit cut-over threshold given. Expect the default 10s
1080+
assert.EqualValues(t, 10, cutOverThresholdSeconds)
10651081
}
10661082
})
10671083
})
@@ -1088,6 +1104,13 @@ func testScheduler(t *testing.T) {
10881104
executedUUID := testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy, "vtctl", "", "", true)) // skip wait
10891105
require.Equal(t, uuid, executedUUID)
10901106

1107+
t.Run("set low cut-over threshold", func(t *testing.T) {
1108+
onlineddl.CheckSetMigrationCutOverThreshold(t, &vtParams, shards, uuid, 2*time.Second, "cut-over min value")
1109+
})
1110+
t.Run("set high cut-over threshold", func(t *testing.T) {
1111+
onlineddl.CheckSetMigrationCutOverThreshold(t, &vtParams, shards, uuid, 2000*time.Second, "cut-over max value")
1112+
})
1113+
10911114
// expect it to complete
10921115
status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed)
10931116
fmt.Printf("# Migration status (for debug purposes): <%s>\n", status)
@@ -1098,6 +1121,10 @@ func testScheduler(t *testing.T) {
10981121
for _, row := range rs.Named().Rows {
10991122
retries := row.AsInt64("retries", 0)
11001123
assert.Greater(t, retries, int64(0))
1124+
1125+
cutOverThresholdSeconds := row.AsInt64("cutover_threshold_seconds", 0)
1126+
// Teh default remains unchanged.
1127+
assert.EqualValues(t, 10, cutOverThresholdSeconds)
11011128
}
11021129
})
11031130
})

go/test/endtoend/onlineddl/vtgate_util.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,16 @@ func CheckForceMigrationCutOver(t *testing.T, vtParams *mysql.ConnParams, shards
255255
}
256256
}
257257

258+
// CheckSetMigrationCutOverThreshold sets the cut-over threshold for a given migration.
259+
func CheckSetMigrationCutOverThreshold(t *testing.T, vtParams *mysql.ConnParams, shards []cluster.Shard, uuid string, threshold time.Duration, expectError string) {
260+
query, err := sqlparser.ParseAndBind("alter vitess_migration %a cutover_threshold %a",
261+
sqltypes.StringBindVariable(uuid),
262+
sqltypes.StringBindVariable(threshold.String()),
263+
)
264+
require.NoError(t, err)
265+
_ = VtgateExecQuery(t, vtParams, query, expectError)
266+
}
267+
258268
// CheckMigrationStatus verifies that the migration indicated by given UUID has the given expected status
259269
func CheckMigrationStatus(t *testing.T, vtParams *mysql.ConnParams, shards []cluster.Shard, uuid string, expectStatuses ...schema.OnlineDDLStatus) bool {
260270
ksName := shards[0].PrimaryTablet().VttabletProcess.Keyspace

go/vt/schema/online_ddl.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"regexp"
2525
"strconv"
2626
"strings"
27+
"time"
2728

2829
vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
2930
"vitess.io/vitess/go/vt/sqlparser"
@@ -116,6 +117,7 @@ type OnlineDDL struct {
116117
Retries int64 `json:"retries,omitempty"`
117118
ReadyToComplete int64 `json:"ready_to_complete,omitempty"`
118119
WasReadyToComplete int64 `json:"was_ready_to_complete,omitempty"`
120+
CutOverThreshold time.Duration `json:"cutover_threshold,omitempty"`
119121
}
120122

121123
// ParseOnlineDDLStatement parses the given SQL into a statement and returns the action type of the DDL statement, or error

go/vt/sidecardb/schema/onlineddl/schema_migrations.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ CREATE TABLE IF NOT EXISTS schema_migrations
7676
`removed_foreign_key_names` text NOT NULL,
7777
`last_cutover_attempt_timestamp` timestamp NULL DEFAULT NULL,
7878
`force_cutover` tinyint unsigned NOT NULL DEFAULT '0',
79+
`cutover_threshold_seconds` int unsigned NOT NULL DEFAULT '0',
7980
PRIMARY KEY (`id`),
8081
UNIQUE KEY `uuid_idx` (`migration_uuid`),
8182
KEY `keyspace_shard_idx` (`keyspace`(64), `shard`(64)),

go/vt/sqlparser/ast.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -491,11 +491,12 @@ type (
491491

492492
// AlterMigration represents a ALTER VITESS_MIGRATION statement
493493
AlterMigration struct {
494-
Type AlterMigrationType
495-
UUID string
496-
Expire string
497-
Ratio *Literal
498-
Shards string
494+
Type AlterMigrationType
495+
UUID string
496+
Expire string
497+
Ratio *Literal
498+
Threshold string
499+
Shards string
499500
}
500501

501502
// AlterTable represents a ALTER TABLE statement.

go/vt/sqlparser/ast_equals.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/vt/sqlparser/ast_format.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,13 @@ func (node *AlterMigration) Format(buf *TrackedBuffer) {
322322
alterType = "force_cutover"
323323
case ForceCutOverAllMigrationType:
324324
alterType = "force_cutover all"
325+
case SetCutOverThresholdMigrationType:
326+
alterType = "cutover_threshold"
325327
}
326328
buf.astPrintf(node, " %#s", alterType)
329+
if node.Threshold != "" {
330+
buf.astPrintf(node, " '%#s'", node.Threshold)
331+
}
327332
if node.Expire != "" {
328333
buf.astPrintf(node, " expire '%#s'", node.Expire)
329334
}

go/vt/sqlparser/ast_format_fast.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/vt/sqlparser/cached_size.go

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/vt/sqlparser/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ const (
915915
UnthrottleAllMigrationType
916916
ForceCutOverMigrationType
917917
ForceCutOverAllMigrationType
918+
SetCutOverThresholdMigrationType
918919
)
919920

920921
// ColumnStorage constants

go/vt/sqlparser/keywords.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ var keywords = []keyword{
205205
{"current_timestamp", CURRENT_TIMESTAMP},
206206
{"current_user", CURRENT_USER},
207207
{"cursor", UNUSED},
208+
{"cutover_threshold", CUTOVER_THRESHOLD},
208209
{"data", DATA},
209210
{"database", DATABASE},
210211
{"databases", DATABASES},

go/vt/sqlparser/parse_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,8 @@ var (
24822482
input: "alter vitess_migration force_cutover all",
24832483
}, {
24842484
input: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' force_cutover",
2485+
}, {
2486+
input: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' cutover_threshold '17s'",
24852487
}, {
24862488
input: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' FORCE_CUTOVER",
24872489
output: "alter vitess_migration '9748c3b7_7fdb_11eb_ac2c_f875a4d24e90' force_cutover",

0 commit comments

Comments
 (0)