From 7e1a6ad9ed5b1f36b3d018e0b5533790e50c3126 Mon Sep 17 00:00:00 2001 From: Yongqiang YANG <98214048+dataroaring@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:05:44 +0800 Subject: [PATCH] [fix](readconsistency) avoid table not exist error (#37593) Query following createting table would throw table not exist error. For example. t1: client issue create table to master fe t2: client issue query sql to observer fe, the query would fail due to not exist table in plan phase. t3: observer fe receive editlog creating the table from the master fe After the pr: query at t2 would wait until latest edit log is received from master fe in the observer fe. --- .../org/apache/doris/qe/StmtExecutor.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index a429ea85ba2782..3c74017c1ba368 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -693,6 +693,13 @@ private void executeByNereids(TUniqueId queryId) throws Exception { return; } } + + // Query following createting table would throw table not exist error. + // For example. + // t1: client issues create table to master fe + // t2: client issues query sql to observer fe, the query would fail due to not exist table in plan phase. + // t3: observer fe receive editlog creating the table from the master fe + syncJournalIfNeeded(); try { ((Command) logicalPlan).run(context, this); } catch (MustFallbackException e) { @@ -727,6 +734,13 @@ private void executeByNereids(TUniqueId queryId) throws Exception { } else { context.getState().setIsQuery(true); // create plan + // Query following createting table would throw table not exist error. + // For example. + // t1: client issues create table to master fe + // t2: client issues query sql to observer fe, the query would fail due to not exist table in + // plan phase. + // t3: observer fe receive editlog creating the table from the master fe + syncJournalIfNeeded(); planner = new NereidsPlanner(statementContext); if (context.getSessionVariable().isEnableMaterializedViewRewrite()) { planner.addHook(InitMaterializationContextHook.INSTANCE); @@ -772,8 +786,6 @@ public void finalizeQuery() { private void handleQueryWithRetry(TUniqueId queryId) throws Exception { // queue query here - syncJournalIfNeeded(); - int retryTime = Config.max_query_retry_time; for (int i = 0; i < retryTime; i++) { try { @@ -863,6 +875,13 @@ public void executeByLegacy(TUniqueId queryId) throws Exception { } } } else { + // Query following createting table would throw table not exist error. + // For example. + // t1: client issues create table to master fe + // t2: client issues query sql to observer fe, the query would fail due to not exist table + // in plan phase. + // t3: observer fe receive editlog creating the table from the master fe + syncJournalIfNeeded(); analyzer = new Analyzer(context.getEnv(), context); parsedStmt.analyze(analyzer); parsedStmt.checkPriv(); @@ -1071,7 +1090,7 @@ public void updateProfile(boolean isFinished) { } // Analyze one statement to structure in memory. - public void analyze(TQueryOptions tQueryOptions) throws UserException, InterruptedException { + public void analyze(TQueryOptions tQueryOptions) throws UserException, InterruptedException, Exception { if (LOG.isDebugEnabled()) { LOG.debug("begin to analyze stmt: {}, forwarded stmt id: {}", context.getStmtId(), context.getForwardedStmtId()); @@ -1113,6 +1132,13 @@ public void analyze(TQueryOptions tQueryOptions) throws UserException, Interrupt return; } + // Query following createting table would throw table not exist error. + // For example. + // t1: client issues create table to master fe + // t2: client issues query sql to observer fe, the query would fail due to not exist table in + // plan phase. + // t3: observer fe receive editlog creating the table from the master fe + syncJournalIfNeeded(); analyzer = new Analyzer(context.getEnv(), context); if (parsedStmt instanceof PrepareStmt || context.getCommand() == MysqlCommand.COM_STMT_PREPARE) {