From 4bdcbb74ab3b3c9232543f3747f81a15ca453b70 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 09:38:13 +0200 Subject: [PATCH] VTGate MoveTables Buffering: Fix panic when buffering is disabled (#16922) Signed-off-by: Rohit Nayak Signed-off-by: Harshit Gangal Co-authored-by: Harshit Gangal --- go/vt/vtgate/executor_test.go | 14 ++++++++++++++ go/vt/vtgate/plan_execute.go | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 1cd58b31cc3..72cb6e4b4e7 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -1520,6 +1520,20 @@ func TestExecutorUnrecognized(t *testing.T) { require.Error(t, err, "unrecognized statement: invalid statement'") } +func TestExecutorDeniedErrorNoBuffer(t *testing.T) { + executor, sbc1, _, _, ctx := createExecutorEnv(t) + sbc1.EphemeralShardErr = errors.New("enforce denied tables") + + vschemaWaitTimeout = 500 * time.Millisecond + + session := NewAutocommitSession(&vtgatepb.Session{TargetString: "@primary"}) + startExec := time.Now() + _, err := executor.Execute(ctx, nil, "TestExecutorDeniedErrorNoBuffer", session, "select * from user", nil) + require.NoError(t, err, "enforce denied tables not buffered") + endExec := time.Now() + require.GreaterOrEqual(t, endExec.Sub(startExec).Milliseconds(), int64(500)) +} + // TestVSchemaStats makes sure the building and displaying of the // VSchemaStats works. func TestVSchemaStats(t *testing.T) { diff --git a/go/vt/vtgate/plan_execute.go b/go/vt/vtgate/plan_execute.go index 34abe5a2aa3..1c0915470ef 100644 --- a/go/vt/vtgate/plan_execute.go +++ b/go/vt/vtgate/plan_execute.go @@ -36,6 +36,8 @@ import ( type planExec func(ctx context.Context, plan *engine.Plan, vc *vcursorImpl, bindVars map[string]*querypb.BindVariable, startTime time.Time) error type txResult func(sqlparser.StatementType, *sqltypes.Result) error +var vschemaWaitTimeout = 30 * time.Second + func waitForNewerVSchema(ctx context.Context, e *Executor, lastVSchemaCreated time.Time, timeout time.Duration) bool { pollingInterval := 10 * time.Millisecond waitCtx, cancel := context.WithTimeout(ctx, timeout) @@ -104,7 +106,10 @@ func (e *Executor) newExecute( // based on the buffering configuration. This way we should be able to perform the max retries // within the given window of time for most queries and we should not end up waiting too long // after the traffic switch fails or the buffer window has ended, retrying old queries. - timeout := e.resolver.scatterConn.gateway.buffer.GetConfig().MaxFailoverDuration / (MaxBufferingRetries - 1) + timeout := vschemaWaitTimeout + if e.resolver.scatterConn.gateway.buffer != nil && e.resolver.scatterConn.gateway.buffer.GetConfig() != nil { + timeout = e.resolver.scatterConn.gateway.buffer.GetConfig().MaxFailoverDuration / (MaxBufferingRetries - 1) + } if waitForNewerVSchema(ctx, e, lastVSchemaCreated, timeout) { vs = e.VSchema() lastVSchemaCreated = vs.GetCreated()