Skip to content

Commit a960b91

Browse files
authored
Online DDL: improved row estimation via ANALYE TABLE with --analyze-table strategy flag (#13352)
* DDL Strategy: support --analyze-table flag Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * Issue an ANALYZE TABLE if --analyze-table is given. Also, update table_rows if rows_copied exceeds it Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * use NO_WRITE_TO_BINLOG Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * update workflows Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --------- Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
1 parent 9699f11 commit a960b91

5 files changed

Lines changed: 37 additions & 3 deletions

File tree

go/vt/schema/ddl_strategy.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const (
4545
cutOverThresholdFlag = "cut-over-threshold"
4646
vreplicationTestSuite = "vreplication-test-suite"
4747
allowForeignKeysFlag = "unsafe-allow-foreign-keys"
48+
analyzeTableFlag = "analyze-table"
4849
)
4950

5051
// DDLStrategy suggests how an ALTER TABLE should run (e.g. "direct", "online", "gh-ost" or "pt-osc")
@@ -221,6 +222,11 @@ func (setting *DDLStrategySetting) IsAllowForeignKeysFlag() bool {
221222
return setting.hasFlag(allowForeignKeysFlag)
222223
}
223224

225+
// IsAnalyzeTableFlag checks if strategy options include --analyze-table
226+
func (setting *DDLStrategySetting) IsAnalyzeTableFlag() bool {
227+
return setting.hasFlag(analyzeTableFlag)
228+
}
229+
224230
// RuntimeOptions returns the options used as runtime flags for given strategy, removing any internal hint options
225231
func (setting *DDLStrategySetting) RuntimeOptions() []string {
226232
opts, _ := shlex.Split(setting.Options)
@@ -243,6 +249,7 @@ func (setting *DDLStrategySetting) RuntimeOptions() []string {
243249
case isFlag(opt, fastRangeRotationFlag):
244250
case isFlag(opt, vreplicationTestSuite):
245251
case isFlag(opt, allowForeignKeysFlag):
252+
case isFlag(opt, analyzeTableFlag):
246253
default:
247254
validOpts = append(validOpts, opt)
248255
}

go/vt/schema/ddl_strategy_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ func TestParseDDLStrategy(t *testing.T) {
116116
fastOverRevertible bool
117117
fastRangeRotation bool
118118
allowForeignKeys bool
119+
analyzeTable bool
119120
cutOverThreshold time.Duration
120121
runtimeOptions string
121122
err error
@@ -238,6 +239,13 @@ func TestParseDDLStrategy(t *testing.T) {
238239
runtimeOptions: "",
239240
cutOverThreshold: 5 * time.Minute,
240241
},
242+
{
243+
strategyVariable: "vitess --analyze-table",
244+
strategy: DDLStrategyVitess,
245+
options: "--analyze-table",
246+
runtimeOptions: "",
247+
analyzeTable: true,
248+
},
241249
}
242250
for _, ts := range tt {
243251
t.Run(ts.strategyVariable, func(t *testing.T) {
@@ -253,6 +261,7 @@ func TestParseDDLStrategy(t *testing.T) {
253261
assert.Equal(t, ts.fastOverRevertible, setting.IsPreferInstantDDL())
254262
assert.Equal(t, ts.fastRangeRotation, setting.IsFastRangeRotationFlag())
255263
assert.Equal(t, ts.allowForeignKeys, setting.IsAllowForeignKeysFlag())
264+
assert.Equal(t, ts.analyzeTable, setting.IsAnalyzeTableFlag())
256265
cutOverThreshold, err := setting.CutOverThreshold()
257266
assert.NoError(t, err)
258267
assert.Equal(t, ts.cutOverThreshold, cutOverThreshold)

go/vt/vttablet/onlineddl/executor.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ func (e *Executor) initVreplicationOriginalMigration(ctx context.Context, online
13161316
}
13171317
}
13181318
}
1319-
v = NewVRepl(onlineDDL.UUID, e.keyspace, e.shard, e.dbName, onlineDDL.Table, vreplTableName, onlineDDL.SQL)
1319+
v = NewVRepl(onlineDDL.UUID, e.keyspace, e.shard, e.dbName, onlineDDL.Table, vreplTableName, onlineDDL.SQL, onlineDDL.StrategySetting().IsAnalyzeTableFlag())
13201320
return v, nil
13211321
}
13221322

@@ -1370,7 +1370,7 @@ func (e *Executor) initVreplicationRevertMigration(ctx context.Context, onlineDD
13701370
if err := e.updateArtifacts(ctx, onlineDDL.UUID, vreplTableName); err != nil {
13711371
return v, err
13721372
}
1373-
v = NewVRepl(onlineDDL.UUID, e.keyspace, e.shard, e.dbName, onlineDDL.Table, vreplTableName, "")
1373+
v = NewVRepl(onlineDDL.UUID, e.keyspace, e.shard, e.dbName, onlineDDL.Table, vreplTableName, "", false)
13741374
v.pos = revertStream.pos
13751375
return v, nil
13761376
}
@@ -4207,6 +4207,7 @@ func (e *Executor) updateMigrationProgress(ctx context.Context, uuid string, pro
42074207

42084208
func (e *Executor) updateMigrationProgressByRowsCopied(ctx context.Context, uuid string, rowsCopied int64) error {
42094209
query, err := sqlparser.ParseAndBind(sqlUpdateMigrationProgressByRowsCopied,
4210+
sqltypes.Int64BindVariable(rowsCopied),
42104211
sqltypes.Int64BindVariable(rowsCopied),
42114212
sqltypes.StringBindVariable(uuid),
42124213
)

go/vt/vttablet/onlineddl/schema.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ const (
213213
`
214214
sqlUpdateMigrationProgressByRowsCopied = `UPDATE _vt.schema_migrations
215215
SET
216+
table_rows=GREATEST(table_rows, %a),
216217
progress=CASE
217218
WHEN table_rows=0 THEN 100
218219
ELSE LEAST(100, 100*%a/table_rows)
@@ -520,6 +521,7 @@ const (
520521
sqlDropTableIfExists = "DROP TABLE IF EXISTS `%a`"
521522
sqlShowColumnsFrom = "SHOW COLUMNS FROM `%a`"
522523
sqlShowTableStatus = "SHOW TABLE STATUS LIKE '%a'"
524+
sqlAnalyzeTable = "ANALYZE NO_WRITE_TO_BINLOG TABLE `%a`"
523525
sqlShowCreateTable = "SHOW CREATE TABLE `%a`"
524526
sqlGetAutoIncrement = `
525527
SELECT

go/vt/vttablet/onlineddl/vrepl.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ type VRepl struct {
104104
alterQuery string
105105
tableRows int64
106106

107+
analyzeTable bool
108+
107109
sourceSharedColumns *vrepl.ColumnList
108110
targetSharedColumns *vrepl.ColumnList
109111
droppedSourceNonGeneratedColumns *vrepl.ColumnList
@@ -130,7 +132,7 @@ type VRepl struct {
130132
}
131133

132134
// NewVRepl creates a VReplication handler for Online DDL
133-
func NewVRepl(workflow, keyspace, shard, dbName, sourceTable, targetTable, alterQuery string) *VRepl {
135+
func NewVRepl(workflow, keyspace, shard, dbName, sourceTable, targetTable, alterQuery string, analyzeTable bool) *VRepl {
134136
return &VRepl{
135137
workflow: workflow,
136138
keyspace: keyspace,
@@ -139,6 +141,7 @@ func NewVRepl(workflow, keyspace, shard, dbName, sourceTable, targetTable, alter
139141
sourceTable: sourceTable,
140142
targetTable: targetTable,
141143
alterQuery: alterQuery,
144+
analyzeTable: analyzeTable,
142145
parser: vrepl.NewAlterTableParser(),
143146
enumToTextMap: map[string]string{},
144147
intToEnumMap: map[string]bool{},
@@ -226,6 +229,13 @@ func (v *VRepl) readTableUniqueKeys(ctx context.Context, conn *dbconnpool.DBConn
226229
return uniqueKeys, nil
227230
}
228231

232+
// executeAnalyzeTable runs an ANALYZE TABLE command
233+
func (v *VRepl) executeAnalyzeTable(ctx context.Context, conn *dbconnpool.DBConnection, tableName string) error {
234+
parsed := sqlparser.BuildParsedQuery(sqlAnalyzeTable, tableName)
235+
_, err := conn.ExecuteFetch(parsed.Query, 1, false)
236+
return err
237+
}
238+
229239
// readTableStatus reads table status information
230240
func (v *VRepl) readTableStatus(ctx context.Context, conn *dbconnpool.DBConnection, tableName string) (tableRows int64, err error) {
231241
parsed := sqlparser.BuildParsedQuery(sqlShowTableStatus, tableName)
@@ -335,6 +345,11 @@ func (v *VRepl) analyzeAlter(ctx context.Context) error {
335345
}
336346

337347
func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection) (err error) {
348+
if v.analyzeTable {
349+
if err := v.executeAnalyzeTable(ctx, conn, v.sourceTable); err != nil {
350+
return err
351+
}
352+
}
338353
v.tableRows, err = v.readTableStatus(ctx, conn, v.sourceTable)
339354
if err != nil {
340355
return err

0 commit comments

Comments
 (0)