diff --git a/go/vt/vtgate/dynamicconfig/config.go b/go/vt/vtgate/dynamicconfig/config.go new file mode 100644 index 00000000000..5bb1d991eae --- /dev/null +++ b/go/vt/vtgate/dynamicconfig/config.go @@ -0,0 +1,6 @@ +package dynamicconfig + +type DDL interface { + OnlineEnabled() bool + DirectEnabled() bool +} diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 4c0d1009bd1..c764a6aab08 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -131,7 +131,7 @@ func (cached *DDL) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(64) + size += int64(80) } // field Keyspace *vitess.io/vitess/go/vt/vtgate/vindexes.Keyspace size += cached.Keyspace.CachedSize(true) @@ -145,6 +145,10 @@ func (cached *DDL) CachedSize(alloc bool) int64 { size += cached.NormalDDL.CachedSize(true) // field OnlineDDL *vitess.io/vitess/go/vt/vtgate/engine.OnlineDDL size += cached.OnlineDDL.CachedSize(true) + // field Config vitess.io/vitess/go/vt/vtgate/dynamicconfig.DDL + if cc, ok := cached.Config.(cachedObject); ok { + size += cc.CachedSize(true) + } return size } func (cached *DML) CachedSize(alloc bool) int64 { diff --git a/go/vt/vtgate/engine/ddl.go b/go/vt/vtgate/engine/ddl.go index cfdaa5866dc..d7e17eb4f4f 100644 --- a/go/vt/vtgate/engine/ddl.go +++ b/go/vt/vtgate/engine/ddl.go @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/dynamicconfig" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -42,8 +43,7 @@ type DDL struct { NormalDDL *Send OnlineDDL *OnlineDDL - DirectDDLEnabled bool - OnlineDDLEnabled bool + Config dynamicconfig.DDL CreateTempTable bool } @@ -107,12 +107,12 @@ func (ddl *DDL) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[st switch { case ddl.isOnlineSchemaDDL(): - if !ddl.OnlineDDLEnabled { + if !ddl.Config.OnlineEnabled() { return nil, schema.ErrOnlineDDLDisabled } return vcursor.ExecutePrimitive(ctx, ddl.OnlineDDL, bindVars, wantfields) default: // non online-ddl - if !ddl.DirectDDLEnabled { + if !ddl.Config.DirectEnabled() { return nil, schema.ErrDirectDDLDisabled } return vcursor.ExecutePrimitive(ctx, ddl.NormalDDL, bindVars, wantfields) diff --git a/go/vt/vtgate/engine/ddl_test.go b/go/vt/vtgate/engine/ddl_test.go index 3f7ccb75f70..1d52089bf39 100644 --- a/go/vt/vtgate/engine/ddl_test.go +++ b/go/vt/vtgate/engine/ddl_test.go @@ -27,13 +27,23 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) +type ddlConfig struct{} + +func (ddlConfig) DirectEnabled() bool { + return true +} + +func (ddlConfig) OnlineEnabled() bool { + return true +} + func TestDDL(t *testing.T) { ddl := &DDL{ DDL: &sqlparser.CreateTable{ Table: sqlparser.NewTableName("a"), }, - DirectDDLEnabled: true, - OnlineDDL: &OnlineDDL{}, + Config: ddlConfig{}, + OnlineDDL: &OnlineDDL{}, NormalDDL: &Send{ Keyspace: &vindexes.Keyspace{ Name: "ks", diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 928f42fca30..c56e076e2fd 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1174,7 +1174,11 @@ func (e *Executor) buildStatement( reservedVars *sqlparser.ReservedVars, bindVarNeeds *sqlparser.BindVarNeeds, ) (*engine.Plan, error) { - plan, err := planbuilder.BuildFromStmt(ctx, query, stmt, reservedVars, vcursor, bindVarNeeds, enableOnlineDDL, enableDirectDDL) + cfg := &dynamicViperConfig{ + onlineDDL: enableOnlineDDL, + directDDL: enableDirectDDL, + } + plan, err := planbuilder.BuildFromStmt(ctx, query, stmt, reservedVars, vcursor, bindVarNeeds, cfg) if err != nil { return nil, err } diff --git a/go/vt/vtgate/executor_ddl_test.go b/go/vt/vtgate/executor_ddl_test.go index 3274fd94475..b0e2cf4b873 100644 --- a/go/vt/vtgate/executor_ddl_test.go +++ b/go/vt/vtgate/executor_ddl_test.go @@ -27,8 +27,8 @@ import ( func TestDDLFlags(t *testing.T) { defer func() { - enableOnlineDDL = true - enableDirectDDL = true + enableOnlineDDL.Set(true) + enableDirectDDL.Set(true) }() testcases := []struct { enableDirectDDL bool @@ -57,8 +57,8 @@ func TestDDLFlags(t *testing.T) { t.Run(fmt.Sprintf("%s-%v-%v", testcase.sql, testcase.enableDirectDDL, testcase.enableOnlineDDL), func(t *testing.T) { executor, _, _, _, ctx := createExecutorEnv(t) session := NewSafeSession(&vtgatepb.Session{TargetString: KsTestUnsharded}) - enableDirectDDL = testcase.enableDirectDDL - enableOnlineDDL = testcase.enableOnlineDDL + enableDirectDDL.Set(testcase.enableDirectDDL) + enableOnlineDDL.Set(testcase.enableOnlineDDL) _, err := executor.Execute(ctx, nil, "TestDDLFlags", session, testcase.sql, nil) if testcase.wantErr { require.EqualError(t, err, testcase.err) diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 495564d6571..ca4ccb7ac5a 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -28,6 +28,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/dynamicconfig" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -63,6 +64,16 @@ func singleTable(ks, tbl string) string { return fmt.Sprintf("%s.%s", ks, tbl) } +type staticConfig struct{} + +func (staticConfig) OnlineEnabled() bool { + return true +} + +func (staticConfig) DirectEnabled() bool { + return true +} + // TestBuilder builds a plan for a query based on the specified vschema. // This method is only used from tests func TestBuilder(query string, vschema plancontext.VSchema, keyspace string) (*engine.Plan, error) { @@ -92,12 +103,12 @@ func TestBuilder(query string, vschema plancontext.VSchema, keyspace string) (*e } reservedVars := sqlparser.NewReservedVars("vtg", reserved) - return BuildFromStmt(context.Background(), query, result.AST, reservedVars, vschema, result.BindVarNeeds, true, true) + return BuildFromStmt(context.Background(), query, result.AST, reservedVars, vschema, result.BindVarNeeds, staticConfig{}) } // BuildFromStmt builds a plan based on the AST provided. -func BuildFromStmt(ctx context.Context, query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, bindVarNeeds *sqlparser.BindVarNeeds, enableOnlineDDL, enableDirectDDL bool) (*engine.Plan, error) { - planResult, err := createInstructionFor(ctx, query, stmt, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) +func BuildFromStmt(ctx context.Context, query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, bindVarNeeds *sqlparser.BindVarNeeds, cfg dynamicconfig.DDL) (*engine.Plan, error) { + planResult, err := createInstructionFor(ctx, query, stmt, reservedVars, vschema, cfg) if err != nil { return nil, err } @@ -154,7 +165,7 @@ func buildRoutePlan(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVa return f(stmt, reservedVars, vschema) } -func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { +func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { switch stmt := stmt.(type) { case *sqlparser.Select, *sqlparser.Insert, *sqlparser.Update, *sqlparser.Delete: configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) @@ -169,13 +180,13 @@ func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Stat } return buildRoutePlan(stmt, reservedVars, vschema, configuredPlanner) case sqlparser.DDLStatement: - return buildGeneralDDLPlan(ctx, query, stmt, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) + return buildGeneralDDLPlan(ctx, query, stmt, reservedVars, vschema, cfg) case *sqlparser.AlterMigration: - return buildAlterMigrationPlan(query, stmt, vschema, enableOnlineDDL) + return buildAlterMigrationPlan(query, stmt, vschema, cfg) case *sqlparser.RevertMigration: - return buildRevertMigrationPlan(query, stmt, vschema, enableOnlineDDL) + return buildRevertMigrationPlan(query, stmt, vschema, cfg) case *sqlparser.ShowMigrationLogs: - return buildShowMigrationLogsPlan(query, vschema, enableOnlineDDL) + return buildShowMigrationLogsPlan(query, vschema, cfg) case *sqlparser.ShowThrottledApps: return buildShowThrottledAppsPlan(query, vschema) case *sqlparser.ShowThrottlerStatus: @@ -189,7 +200,7 @@ func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Stat case *sqlparser.ExplainStmt: return buildRoutePlan(stmt, reservedVars, vschema, buildExplainStmtPlan) case *sqlparser.VExplainStmt: - return buildVExplainPlan(ctx, stmt, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) + return buildVExplainPlan(ctx, stmt, reservedVars, vschema, cfg) case *sqlparser.OtherAdmin: return buildOtherReadAndAdmin(query, vschema) case *sqlparser.Analyze: diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index 5e16dab1c59..a0045cec060 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -9,6 +9,7 @@ import ( vschemapb "vitess.io/vitess/go/vt/proto/vschema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/dynamicconfig" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -43,11 +44,11 @@ func (fk *fkContraint) FkWalk(node sqlparser.SQLNode) (kontinue bool, err error) // a session context. It's only when we Execute() the primitive that we have that context. // This is why we return a compound primitive (DDL) which contains fully populated primitives (Send & OnlineDDL), // and which chooses which of the two to invoke at runtime. -func buildGeneralDDLPlan(ctx context.Context, sql string, ddlStatement sqlparser.DDLStatement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { +func buildGeneralDDLPlan(ctx context.Context, sql string, ddlStatement sqlparser.DDLStatement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { if vschema.Destination() != nil { return buildByPassPlan(sql, vschema, true) } - normalDDLPlan, onlineDDLPlan, err := buildDDLPlans(ctx, sql, ddlStatement, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) + normalDDLPlan, onlineDDLPlan, err := buildDDLPlans(ctx, sql, ddlStatement, reservedVars, vschema, cfg) if err != nil { return nil, err } @@ -61,15 +62,12 @@ func buildGeneralDDLPlan(ctx context.Context, sql string, ddlStatement sqlparser } eddl := &engine.DDL{ - Keyspace: normalDDLPlan.Keyspace, - SQL: normalDDLPlan.Query, - DDL: ddlStatement, - NormalDDL: normalDDLPlan, - OnlineDDL: onlineDDLPlan, - - DirectDDLEnabled: enableDirectDDL, - OnlineDDLEnabled: enableOnlineDDL, - + Keyspace: normalDDLPlan.Keyspace, + SQL: normalDDLPlan.Query, + DDL: ddlStatement, + NormalDDL: normalDDLPlan, + OnlineDDL: onlineDDLPlan, + Config: cfg, CreateTempTable: ddlStatement.IsTemporary(), } tc := &tableCollector{} @@ -94,7 +92,7 @@ func buildByPassPlan(sql string, vschema plancontext.VSchema, isDDL bool) (*plan return newPlanResult(send), nil } -func buildDDLPlans(ctx context.Context, sql string, ddlStatement sqlparser.DDLStatement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*engine.Send, *engine.OnlineDDL, error) { +func buildDDLPlans(ctx context.Context, sql string, ddlStatement sqlparser.DDLStatement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*engine.Send, *engine.OnlineDDL, error) { var destination key.Destination var keyspace *vindexes.Keyspace var err error @@ -113,9 +111,9 @@ func buildDDLPlans(ctx context.Context, sql string, ddlStatement sqlparser.DDLSt } err = checkFKError(vschema, ddlStatement, keyspace) case *sqlparser.CreateView: - destination, keyspace, err = buildCreateViewCommon(ctx, vschema, reservedVars, enableOnlineDDL, enableDirectDDL, ddl.Select, ddl) + destination, keyspace, err = buildCreateViewCommon(ctx, vschema, reservedVars, cfg, ddl.Select, ddl) case *sqlparser.AlterView: - destination, keyspace, err = buildCreateViewCommon(ctx, vschema, reservedVars, enableOnlineDDL, enableDirectDDL, ddl.Select, ddl) + destination, keyspace, err = buildCreateViewCommon(ctx, vschema, reservedVars, cfg, ddl.Select, ddl) case *sqlparser.DropView: destination, keyspace, err = buildDropView(vschema, ddlStatement) case *sqlparser.DropTable: @@ -197,7 +195,7 @@ func buildCreateViewCommon( ctx context.Context, vschema plancontext.VSchema, reservedVars *sqlparser.ReservedVars, - enableOnlineDDL, enableDirectDDL bool, + cfg dynamicconfig.DDL, ddlSelect sqlparser.SelectStatement, ddl sqlparser.DDLStatement, ) (key.Destination, *vindexes.Keyspace, error) { @@ -214,7 +212,7 @@ func buildCreateViewCommon( expressions = append(expressions, sqlparser.Clone(p.SelectExprs)) return nil }) - selectPlan, err := createInstructionFor(ctx, sqlparser.String(ddlSelect), ddlSelect, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) + selectPlan, err := createInstructionFor(ctx, sqlparser.String(ddlSelect), ddlSelect, reservedVars, vschema, cfg) if err != nil { return nil, nil, err } diff --git a/go/vt/vtgate/planbuilder/migration.go b/go/vt/vtgate/planbuilder/migration.go index 6fb73a9039d..e64b990aa6b 100644 --- a/go/vt/vtgate/planbuilder/migration.go +++ b/go/vt/vtgate/planbuilder/migration.go @@ -27,6 +27,7 @@ import ( "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/dynamicconfig" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -80,8 +81,8 @@ func buildAlterMigrationThrottleAppPlan(query string, alterMigration *sqlparser. }), nil } -func buildAlterMigrationPlan(query string, alterMigration *sqlparser.AlterMigration, vschema plancontext.VSchema, enableOnlineDDL bool) (*planResult, error) { - if !enableOnlineDDL { +func buildAlterMigrationPlan(query string, alterMigration *sqlparser.AlterMigration, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { + if !cfg.OnlineEnabled() { return nil, schema.ErrOnlineDDLDisabled } @@ -118,8 +119,8 @@ func buildAlterMigrationPlan(query string, alterMigration *sqlparser.AlterMigrat return newPlanResult(send), nil } -func buildRevertMigrationPlan(query string, stmt *sqlparser.RevertMigration, vschema plancontext.VSchema, enableOnlineDDL bool) (*planResult, error) { - if !enableOnlineDDL { +func buildRevertMigrationPlan(query string, stmt *sqlparser.RevertMigration, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { + if !cfg.OnlineEnabled() { return nil, schema.ErrOnlineDDLDisabled } dest, ks, tabletType, err := vschema.TargetDestination("") @@ -147,8 +148,8 @@ func buildRevertMigrationPlan(query string, stmt *sqlparser.RevertMigration, vsc return newPlanResult(emig), nil } -func buildShowMigrationLogsPlan(query string, vschema plancontext.VSchema, enableOnlineDDL bool) (*planResult, error) { - if !enableOnlineDDL { +func buildShowMigrationLogsPlan(query string, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { + if !cfg.OnlineEnabled() { return nil, schema.ErrOnlineDDLDisabled } dest, ks, tabletType, err := vschema.TargetDestination("") diff --git a/go/vt/vtgate/planbuilder/simplifier_test.go b/go/vt/vtgate/planbuilder/simplifier_test.go index 305c18896e3..c4b9fd71174 100644 --- a/go/vt/vtgate/planbuilder/simplifier_test.go +++ b/go/vt/vtgate/planbuilder/simplifier_test.go @@ -135,12 +135,12 @@ func keepSameError(query string, reservedVars *sqlparser.ReservedVars, vschema * } rewritten, _ := sqlparser.RewriteAST(stmt, vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) ast := rewritten.AST - _, expected := BuildFromStmt(context.Background(), query, ast, reservedVars, vschema, rewritten.BindVarNeeds, true, true) + _, expected := BuildFromStmt(context.Background(), query, ast, reservedVars, vschema, rewritten.BindVarNeeds, staticConfig{}) if expected == nil { panic("query does not fail to plan") } return func(statement sqlparser.SelectStatement) bool { - _, myErr := BuildFromStmt(context.Background(), query, statement, reservedVars, vschema, needs, true, true) + _, myErr := BuildFromStmt(context.Background(), query, statement, reservedVars, vschema, needs, staticConfig{}) if myErr == nil { return false } @@ -162,7 +162,7 @@ func keepPanicking(query string, reservedVars *sqlparser.ReservedVars, vschema * } }() log.Errorf("trying %s", sqlparser.String(statement)) - _, _ = BuildFromStmt(context.Background(), query, statement, reservedVars, vschema, needs, true, true) + _, _ = BuildFromStmt(context.Background(), query, statement, reservedVars, vschema, needs, staticConfig{}) log.Errorf("did not panic") return false diff --git a/go/vt/vtgate/planbuilder/vexplain.go b/go/vt/vtgate/planbuilder/vexplain.go index f66af7bfc33..7aed1e48884 100644 --- a/go/vt/vtgate/planbuilder/vexplain.go +++ b/go/vt/vtgate/planbuilder/vexplain.go @@ -26,6 +26,7 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/dynamicconfig" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -37,15 +38,15 @@ func buildVExplainPlan( vexplainStmt *sqlparser.VExplainStmt, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, - enableOnlineDDL, enableDirectDDL bool, + cfg dynamicconfig.DDL, ) (*planResult, error) { switch vexplainStmt.Type { case sqlparser.QueriesVExplainType, sqlparser.AllVExplainType: - return buildVExplainLoggingPlan(ctx, vexplainStmt, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) + return buildVExplainLoggingPlan(ctx, vexplainStmt, reservedVars, vschema, cfg) case sqlparser.PlanVExplainType: - return buildVExplainVtgatePlan(ctx, vexplainStmt.Statement, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) + return buildVExplainVtgatePlan(ctx, vexplainStmt.Statement, reservedVars, vschema, cfg) case sqlparser.TraceVExplainType: - return buildVExplainTracePlan(ctx, vexplainStmt.Statement, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) + return buildVExplainTracePlan(ctx, vexplainStmt.Statement, reservedVars, vschema, cfg) case sqlparser.KeysVExplainType: return buildVExplainKeysPlan(vexplainStmt.Statement, vschema) } @@ -92,8 +93,8 @@ func explainTabPlan(explain *sqlparser.ExplainTab, vschema plancontext.VSchema) }, singleTable(keyspace.Name, explain.Table.Name.String())), nil } -func buildVExplainVtgatePlan(ctx context.Context, explainStatement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { - innerInstruction, err := createInstructionFor(ctx, sqlparser.String(explainStatement), explainStatement, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) +func buildVExplainVtgatePlan(ctx context.Context, explainStatement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { + innerInstruction, err := createInstructionFor(ctx, sqlparser.String(explainStatement), explainStatement, reservedVars, vschema, cfg) if err != nil { return nil, err } @@ -124,8 +125,8 @@ func buildVExplainKeysPlan(statement sqlparser.Statement, vschema plancontext.VS return getJsonResultPlan(result, "ColumnUsage") } -func buildVExplainLoggingPlan(ctx context.Context, explain *sqlparser.VExplainStmt, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { - input, err := createInstructionFor(ctx, sqlparser.String(explain.Statement), explain.Statement, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) +func buildVExplainLoggingPlan(ctx context.Context, explain *sqlparser.VExplainStmt, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { + input, err := createInstructionFor(ctx, sqlparser.String(explain.Statement), explain.Statement, reservedVars, vschema, cfg) if err != nil { return nil, err } @@ -188,8 +189,8 @@ func explainPlan(explain *sqlparser.ExplainStmt, reservedVars *sqlparser.Reserve }, tables...), nil } -func buildVExplainTracePlan(ctx context.Context, explainStatement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { - innerInstruction, err := createInstructionFor(ctx, sqlparser.String(explainStatement), explainStatement, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) +func buildVExplainTracePlan(ctx context.Context, explainStatement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, cfg dynamicconfig.DDL) (*planResult, error) { + innerInstruction, err := createInstructionFor(ctx, sqlparser.String(explainStatement), explainStatement, reservedVars, vschema, cfg) if err != nil { return nil, err } diff --git a/go/vt/vtgate/viperconfig.go b/go/vt/vtgate/viperconfig.go new file mode 100644 index 00000000000..ec77ff62d4f --- /dev/null +++ b/go/vt/vtgate/viperconfig.go @@ -0,0 +1,16 @@ +package vtgate + +import "vitess.io/vitess/go/viperutil" + +type dynamicViperConfig struct { + onlineDDL viperutil.Value[bool] + directDDL viperutil.Value[bool] +} + +func (d *dynamicViperConfig) OnlineEnabled() bool { + return d.onlineDDL.Get() +} + +func (d *dynamicViperConfig) DirectEnabled() bool { + return d.directDDL.Get() +} diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index e9e7cd65011..1628a6253eb 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -34,6 +34,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/tb" + "vitess.io/vitess/go/viperutil" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" @@ -93,8 +94,24 @@ var ( foreignKeyMode = "allow" dbDDLPlugin = "fail" defaultDDLStrategy = string(schema.DDLStrategyDirect) - enableOnlineDDL = true - enableDirectDDL = true + + enableOnlineDDL = viperutil.Configure( + "enable_online_ddl", + viperutil.Options[bool]{ + FlagName: "enable_online_ddl", + Default: true, + Dynamic: true, + }, + ) + + enableDirectDDL = viperutil.Configure( + "enable_direct_ddl", + viperutil.Options[bool]{ + FlagName: "enable_direct_ddl", + Default: true, + Dynamic: true, + }, + ) // schema tracking flags enableSchemaChangeSignal = true @@ -141,8 +158,8 @@ func registerFlags(fs *pflag.FlagSet) { fs.DurationVar(&lockHeartbeatTime, "lock_heartbeat_time", lockHeartbeatTime, "If there is lock function used. This will keep the lock connection active by using this heartbeat") fs.BoolVar(&warnShardedOnly, "warn_sharded_only", warnShardedOnly, "If any features that are only available in unsharded mode are used, query execution warnings will be added to the session") fs.StringVar(&foreignKeyMode, "foreign_key_mode", foreignKeyMode, "This is to provide how to handle foreign key constraint in create/alter table. Valid values are: allow, disallow") - fs.BoolVar(&enableOnlineDDL, "enable_online_ddl", enableOnlineDDL, "Allow users to submit, review and control Online DDL") - fs.BoolVar(&enableDirectDDL, "enable_direct_ddl", enableDirectDDL, "Allow users to submit direct DDL statements") + fs.Bool("enable_online_ddl", enableOnlineDDL.Default(), "Allow users to submit, review and control Online DDL") + fs.Bool("enable_direct_ddl", enableDirectDDL.Default(), "Allow users to submit direct DDL statements") fs.BoolVar(&enableSchemaChangeSignal, "schema_change_signal", enableSchemaChangeSignal, "Enable the schema tracker; requires queryserver-config-schema-change-signal to be enabled on the underlying vttablets for this to work") fs.IntVar(&queryTimeout, "query-timeout", queryTimeout, "Sets the default query timeout (in ms). Can be overridden by session variable (query_timeout) or comment directive (QUERY_TIMEOUT_MS)") fs.StringVar(&queryLogToFile, "log_queries_to_file", queryLogToFile, "Enable query logging to the specified file") @@ -154,6 +171,8 @@ func registerFlags(fs *pflag.FlagSet) { fs.IntVar(&warmingReadsPercent, "warming-reads-percent", 0, "Percentage of reads on the primary to forward to replicas. Useful for keeping buffer pools warm") fs.IntVar(&warmingReadsConcurrency, "warming-reads-concurrency", 500, "Number of concurrent warming reads allowed") fs.DurationVar(&warmingReadsQueryTimeout, "warming-reads-query-timeout", 5*time.Second, "Timeout of warming read queries") + + viperutil.BindFlags(fs, enableOnlineDDL, enableDirectDDL) } func init() {