Skip to content

Commit

Permalink
allow SHOW to stop blocking queries after a VT15001
Browse files Browse the repository at this point in the history
Signed-off-by: Florent Poinsard <florent.poinsard@outlook.fr>
  • Loading branch information
frouioui committed Feb 24, 2025
1 parent 5baee4d commit f10eb16
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func testExecuteError(t *testing.T, conn *mysql.Conn, clusterInstance *cluster.L
_, err = conn.ExecuteFetch("select * from vt_insert_test", 1, false)
require.ErrorContains(t, err, "VT15002")

_, err = conn.ExecuteFetch("rollback", 0, false)
_, err = conn.ExecuteFetch("show warnings", 0, false)
require.NoError(t, err)
executeDone <- true
}()
Expand Down
4 changes: 2 additions & 2 deletions go/vt/vterrors/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ var (
VT14004 = errorWithoutState("VT14004", vtrpcpb.Code_UNAVAILABLE, "cannot find keyspace for: %s", "The specified keyspace could not be found.")
VT14005 = errorWithoutState("VT14005", vtrpcpb.Code_UNAVAILABLE, "cannot lookup sidecar database for keyspace: %s", "Failed to read sidecar database identifier.")

VT15001 = errorWithNoCode("VT15001", "transient transaction error, please issue a ROLLBACK and retry the transaction: %s", "The opened transaction must be ROLLBACK by the application and re-tried.")
VT15002 = errorWithoutState("VT15002", vtrpcpb.Code_FAILED_PRECONDITION, "previous transaction failed fatally: issue a ROLLBACK query in order to acknowledge the failed transaction", "This error appears after a VT15001 error was sent back to the client, future queries on the same session will fail until a ROLLBACK is explicitly sent to VTGate.")
VT15001 = errorWithNoCode("VT15001", "transient transaction error, please issue a ROLLBACK or SHOW WARNINGS and retry the transaction: %s", "The opened transaction must be ROLLBACK by the application and re-tried.")
VT15002 = errorWithoutState("VT15002", vtrpcpb.Code_FAILED_PRECONDITION, "previous transaction failed fatally: issue a ROLLBACK or SHOW WARNINGS query in order to acknowledge the failed transaction", "This error appears after a VT15001 error was sent back to the client, future queries on the same session will fail until the client acknowledge the situation by a sending a ROLLBACK or SHOW WARNINGS query.")

// Errors is a list of errors that must match all the variables
// defined above to enable auto-documentation of error codes.
Expand Down
1 change: 0 additions & 1 deletion go/vt/vtgate/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,6 @@ func (e *Executor) handleRollback(ctx context.Context, safeSession *econtext.Saf
e.updateQueryCounts("Rollback", "", "", int64(logStats.ShardQueries))
err := e.txConn.Rollback(ctx, safeSession)
logStats.CommitTime = time.Since(execStart)
safeSession.SetErrorUntilRollback(false) // We have executed a ROLLBACK, if applicable: we can stop blocking queries on this session
return &sqltypes.Result{}, err
}

Expand Down
15 changes: 13 additions & 2 deletions go/vt/vtgate/plan_execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ func (e *Executor) newExecute(
ctx, cancel = vcursor.GetContextWithTimeOut(ctx)
defer cancel()

// If we have previously issued a VT15001 error, we block every queries on this session until we receive a ROLLBACK.
if plan.Type != sqlparser.StmtRollback && safeSession.IsErrorUntilRollback() {
// If we have previously issued a VT15001 error, we block every queries on this session until we receive a ROLLBACK or "show warnings".
if shouldBlockQuery(plan, safeSession) {
return vterrors.VT15002()
}

Expand Down Expand Up @@ -444,3 +444,14 @@ func (e *Executor) logPlanningFinished(logStats *logstats.LogStats, plan *engine
logStats.PlanTime = execStart.Sub(logStats.StartTime)
return execStart
}

func shouldBlockQuery(plan *engine.Plan, safeSession *econtext.SafeSession) bool {
block := safeSession.IsErrorUntilRollback()
if plan.Type != sqlparser.StmtRollback && plan.Type != sqlparser.StmtShow && block {
return true
}
if block {
safeSession.SetErrorUntilRollback(false)
}
return false
}

0 comments on commit f10eb16

Please sign in to comment.