[opt](Nereids) do not fallback if nereids failed because timeout (#39499) (#39718)

pick from master #39499

since legacy planner will cost more time to plan, fallback will be worse
than throw exception directly
This commit is contained in:
morrySnow
2024-08-22 00:45:23 +08:00
committed by GitHub
parent a55e109e97
commit 92671cbb73
4 changed files with 90 additions and 13 deletions

View File

@ -0,0 +1,27 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.nereids.exceptions;
/**
* Exception for can not fall back error in Nereids.
*/
public class DoNotFallbackException extends RuntimeException {
public DoNotFallbackException(String msg) {
super(msg);
}
}

View File

@ -18,6 +18,7 @@
package org.apache.doris.nereids.jobs.scheduler;
import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.exceptions.DoNotFallbackException;
import org.apache.doris.nereids.jobs.Job;
import org.apache.doris.qe.SessionVariable;
@ -36,7 +37,7 @@ public class SimpleJobScheduler implements JobScheduler {
if (sessionVariable.enableNereidsTimeout
&& context.getStatementContext().getStopwatch().elapsed(TimeUnit.MILLISECONDS)
> sessionVariable.nereidsTimeoutSecond * 1000L) {
throw new RuntimeException(
throw new DoNotFallbackException(
"Nereids cost too much time ( > " + sessionVariable.nereidsTimeoutSecond + "s )");
}
Job job = pool.pop();

View File

@ -136,6 +136,7 @@ import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.nereids.NereidsPlanner;
import org.apache.doris.nereids.PlanProcess;
import org.apache.doris.nereids.StatementContext;
import org.apache.doris.nereids.exceptions.DoNotFallbackException;
import org.apache.doris.nereids.exceptions.MustFallbackException;
import org.apache.doris.nereids.exceptions.ParseException;
import org.apache.doris.nereids.glue.LogicalPlanAdapter;
@ -520,7 +521,10 @@ public class StmtExecutor {
execute(queryId);
}
public boolean notAllowFallback() {
public boolean notAllowFallback(NereidsException e) {
if (e.getException() instanceof DoNotFallbackException) {
return true;
}
if (parsedStmt instanceof LogicalPlanAdapter) {
LogicalPlan logicalPlan = ((LogicalPlanAdapter) parsedStmt).getLogicalPlan();
return logicalPlan instanceof NotAllowFallback;
@ -545,12 +549,12 @@ public class StmtExecutor {
}
// try to fall back to legacy planner
if (LOG.isDebugEnabled()) {
LOG.debug("nereids cannot process statement\n" + originStmt.originStmt
+ "\n because of " + e.getMessage(), e);
LOG.debug("nereids cannot process statement\n{}\n because of {}",
originStmt.originStmt, e.getMessage(), e);
}
if (notAllowFallback()) {
if (e instanceof NereidsException && notAllowFallback((NereidsException) e)) {
LOG.warn("Analyze failed. {}", context.getQueryIdentifier(), e);
throw ((NereidsException) e).getException();
throw new AnalysisException(e.getMessage());
}
// FIXME: Force fallback for:
// 1. group commit because nereids does not support it (see the following `isGroupCommit` variable)
@ -709,7 +713,7 @@ public class StmtExecutor {
syncJournalIfNeeded();
try {
((Command) logicalPlan).run(context, this);
} catch (MustFallbackException e) {
} catch (MustFallbackException | DoNotFallbackException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Command({}) process failed.", originStmt.originStmt, e);
}
@ -755,10 +759,11 @@ public class StmtExecutor {
try {
planner.plan(parsedStmt, context.getSessionVariable().toThrift());
checkBlockRules();
} catch (MustFallbackException | DoNotFallbackException e) {
LOG.warn("Nereids plan query failed:\n{}", originStmt.originStmt, e);
throw new NereidsException("Command(" + originStmt.originStmt + ") process failed.", e);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Nereids plan query failed:\n{}", originStmt.originStmt);
}
LOG.warn("Nereids plan query failed:\n{}", originStmt.originStmt, e);
throw new NereidsException(new AnalysisException(e.getMessage(), e));
}
profile.getSummaryProfile().setQueryPlanFinishTime();
@ -3300,10 +3305,10 @@ public class StmtExecutor {
}
// try to fall back to legacy planner
if (LOG.isDebugEnabled()) {
LOG.debug("nereids cannot process statement\n" + originStmt.originStmt
+ "\n because of " + e.getMessage(), e);
LOG.debug("nereids cannot process statement\n{}\n because of {}",
originStmt.originStmt, e.getMessage(), e);
}
if (notAllowFallback()) {
if (e instanceof NereidsException && notAllowFallback((NereidsException) e)) {
LOG.warn("Analyze failed. {}", context.getQueryIdentifier(), e);
throw ((NereidsException) e).getException();
}