Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SHOW VITESS_MIGRATIONS from inside a transaction #16399

Merged
merged 4 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,11 @@ func testScheduler(t *testing.T) {
}
})
})
t.Run("show vitess_migrations in transaction", func(t *testing.T) {
// The function validates there is no error
rs := onlineddl.VtgateExecQueryInTransaction(t, &vtParams, "show vitess_migrations", "")
assert.NotEmpty(t, rs.Rows)
})

forceCutoverCapable, err := capableOf(capabilities.PerformanceSchemaDataLocksTableCapability) // 8.0
require.NoError(t, err)
Expand Down
23 changes: 23 additions & 0 deletions go/test/endtoend/onlineddl/vtgate_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@ func VtgateExecQuery(t *testing.T, vtParams *mysql.ConnParams, query string, exp
return qr
}

// VtgateExecQueryInTransaction runs a query on VTGate using given query params, inside a transaction
func VtgateExecQueryInTransaction(t *testing.T, vtParams *mysql.ConnParams, query string, expectError string) *sqltypes.Result {
t.Helper()

ctx := context.Background()
conn, err := mysql.Connect(ctx, vtParams)
require.Nil(t, err)
defer conn.Close()

_, err = conn.ExecuteFetch("begin", -1, true)
require.NoError(t, err)
qr, err := conn.ExecuteFetch(query, -1, true)
if expectError == "" {
require.NoError(t, err)
} else {
require.Error(t, err, "error should not be nil")
assert.Contains(t, err.Error(), expectError, "Unexpected error")
}
_, err = conn.ExecuteFetch("commit", -1, true)
require.NoError(t, err)
return qr
}

// VtgateExecDDL executes a DDL query with given strategy
func VtgateExecDDL(t *testing.T, vtParams *mysql.ConnParams, ddlStrategy string, query string, expectError string) *sqltypes.Result {
t.Helper()
Expand Down
6 changes: 4 additions & 2 deletions go/vt/vttablet/tabletserver/query_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (qre *QueryExecutor) Execute() (reply *sqltypes.Result, err error) {
case p.PlanRevertMigration:
return qre.execRevertMigration()
case p.PlanShowMigrations:
return qre.execShowMigrations()
return qre.execShowMigrations(nil)
case p.PlanShowMigrationLogs:
return qre.execShowMigrationLogs()
case p.PlanShowThrottledApps:
Expand Down Expand Up @@ -308,6 +308,8 @@ func (qre *QueryExecutor) txConnExec(conn *StatefulConnection) (*sqltypes.Result
return qre.execLoad(conn)
case p.PlanCallProc:
return qre.execProc(conn)
case p.PlanShowMigrations:
return qre.execShowMigrations(conn)
}
return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] %s unexpected plan type", qre.plan.PlanID.String())
}
Expand Down Expand Up @@ -958,7 +960,7 @@ func (qre *QueryExecutor) execRevertMigration() (*sqltypes.Result, error) {
return qre.tsv.onlineDDLExecutor.SubmitMigration(qre.ctx, qre.plan.FullStmt)
}

func (qre *QueryExecutor) execShowMigrations() (*sqltypes.Result, error) {
func (qre *QueryExecutor) execShowMigrations(conn *StatefulConnection) (*sqltypes.Result, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shlomi-noach is conn *StatefulConnection meant to be used here? I don't follow this part

Copy link
Contributor Author

@shlomi-noach shlomi-noach Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes-ish :). I'm not all too familiar with this either, but I got guidance from @harshit-gangal. The StatefulConnection is the standard way for you to implement a transactional behavior working with QueryService. So we should pass that variable. Normally I'd also use the variable -- except:

  • I don't really require show vitess_migrations to exhibit transactional behavior; it's a show command and I don;t need it to e.g. be repeatable-read or anything. I only need it to work from within a transaction.
  • Therefore no need to bloat the transaction.
  • Also, the existing logic uses the executor's own connection pooling, which is fine, and there's no need/reason to now take apart the existing and working mechanism within the executor to accommodate the transactional connection.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok sounds good 👍

if showStmt, ok := qre.plan.FullStmt.(*sqlparser.Show); ok {
return qre.tsv.onlineDDLExecutor.ShowMigrations(qre.ctx, showStmt)
}
Expand Down
Loading