This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 57519fcf50 [fix](information_schema) catch and skip exception when 
getting schema from FE catalog (#16647)
57519fcf50 is described below

commit 57519fcf508c74252fbd0e4d841966e00ff66e29
Author: Mingyu Chen <morning...@163.com>
AuthorDate: Tue Feb 21 08:43:09 2023 +0800

    [fix](information_schema) catch and skip exception when getting schema from 
FE catalog (#16647)
    
    When querying information_schema database, BE will call FE RPC
    to get schema info such as db name list, table name list, etc.
    But some external catalog when failed to get these info because of wrong 
connection info.
    We should catch these kind of exception and skip it, so that it can 
continue to
    get schema info of other catalogs.
    Otherwise, the whole query on information_schema will fail, even if user 
just want to get
    info of internal catalog.
    
    And set jdbc connection timeout to 5s, to avoid thrift rpc timeout from BE 
to FE(default is 30s)
---
 .../org/apache/doris/external/jdbc/JdbcClient.java |   6 ++
 .../apache/doris/service/FrontendServiceImpl.java  | 112 +++++++++++----------
 2 files changed, 67 insertions(+), 51 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java 
b/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java
index 5615de391f..43d8149337 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java
@@ -77,6 +77,12 @@ public class JdbcClient {
             config.setUsername(jdbcUser);
             config.setPassword(password);
             config.setMaximumPoolSize(1);
+            // set connection timeout to 5s.
+            // The default is 30s, which is too long.
+            // Because when querying information_schema db, BE will call 
thrift rpc(default timeout is 30s)
+            // to FE to get schema info, and may create connection here, if we 
set it too long and the url is invalid,
+            // it may cause the thrift rpc timeout.
+            config.setConnectionTimeout(5000);
             dataSource = new HikariDataSource(config);
         } catch (MalformedURLException e) {
             throw new JdbcClientException("MalformedURLException to load class 
about " + driverUrl, e);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java 
b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
index 02c1b55c42..dbcca2d6c0 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
@@ -272,7 +272,15 @@ public class FrontendServiceImpl implements 
FrontendService.Iface {
                     .getCatalogOrException(params.catalog, catalog -> new 
TException("Unknown catalog " + catalog)));
         }
         for (CatalogIf catalog : catalogIfs) {
-            List<String> dbNames = catalog.getDbNamesOrEmpty();
+            List<String> dbNames;
+            try {
+                dbNames = catalog.getDbNamesOrEmpty();
+            } catch (Exception e) {
+                LOG.warn("failed to get database names for catalog {}", 
catalog.getName(), e);
+                // Some external catalog may fail to get databases due to 
wrong connection info.
+                // So continue here to get databases of other catalogs.
+                continue;
+            }
             LOG.debug("get db names: {}, in catalog: {}", dbNames, 
catalog.getName());
 
             UserIdentity currentUser = null;
@@ -491,18 +499,22 @@ public class FrontendServiceImpl implements 
FrontendService.Iface {
                 .getDbNullable(params.db);
 
         if (db != null) {
-            Set<String> tableNames = db.getTableNamesOrEmptyWithLock();
-            for (String tableName : tableNames) {
-                LOG.debug("get table: {}, wait to check", tableName);
-                if (!Env.getCurrentEnv().getAccessManager()
-                        .checkTblPriv(currentUser, params.db, tableName, 
PrivPredicate.SHOW)) {
-                    continue;
-                }
-
-                if (matcher != null && !matcher.match(tableName)) {
-                    continue;
+            Set<String> tableNames;
+            try {
+                tableNames = db.getTableNamesOrEmptyWithLock();
+                for (String tableName : tableNames) {
+                    LOG.debug("get table: {}, wait to check", tableName);
+                    if (!Env.getCurrentEnv().getAccessManager()
+                            .checkTblPriv(currentUser, params.db, tableName, 
PrivPredicate.SHOW)) {
+                        continue;
+                    }
+                    if (matcher != null && !matcher.match(tableName)) {
+                        continue;
+                    }
+                    tablesResult.add(tableName);
                 }
-                tablesResult.add(tableName);
+            } catch (Exception e) {
+                LOG.warn("failed to get table names for db {} in catalog {}", 
params.db, catalogName, e);
             }
         }
         return result;
@@ -540,51 +552,50 @@ public class FrontendServiceImpl implements 
FrontendService.Iface {
         if (catalog != null) {
             DatabaseIf db = catalog.getDbNullable(params.db);
             if (db != null) {
-                List<TableIf> tables = Lists.newArrayList();
-                if (!params.isSetType() || params.getType() == null || 
params.getType().isEmpty()) {
-                    tables = db.getTablesOrEmpty();
-                } else {
-                    switch (params.getType()) {
-                        case "VIEW":
-                            tables = db.getViewsOrEmpty();
-                            break;
-                        default:
-                            tables = db.getTablesOrEmpty();
-                    }
-                }
-                for (TableIf table : tables) {
-                    if 
(!Env.getCurrentEnv().getAccessManager().checkTblPriv(currentUser, params.db,
-                            table.getName(), PrivPredicate.SHOW)) {
-                        continue;
+                try {
+                    List<TableIf> tables;
+                    if (!params.isSetType() || params.getType() == null || 
params.getType().isEmpty()) {
+                        tables = db.getTablesOrEmpty();
+                    } else {
+                        switch (params.getType()) {
+                            case "VIEW":
+                                tables = db.getViewsOrEmpty();
+                                break;
+                            default:
+                                tables = db.getTablesOrEmpty();
+                        }
                     }
-                    table.readLock();
-                    try {
+                    for (TableIf table : tables) {
                         if 
(!Env.getCurrentEnv().getAccessManager().checkTblPriv(currentUser, params.db,
                                 table.getName(), PrivPredicate.SHOW)) {
                             continue;
                         }
-
-                        if (matcher != null && 
!matcher.match(table.getName())) {
-                            continue;
+                        table.readLock();
+                        try {
+                            if (matcher != null && 
!matcher.match(table.getName())) {
+                                continue;
+                            }
+                            long lastCheckTime = table.getLastCheckTime() <= 0 
? 0 : table.getLastCheckTime();
+                            TTableStatus status = new TTableStatus();
+                            status.setName(table.getName());
+                            status.setType(table.getMysqlType());
+                            status.setEngine(table.getEngine());
+                            status.setComment(table.getComment());
+                            status.setCreateTime(table.getCreateTime());
+                            status.setLastCheckTime(lastCheckTime / 1000);
+                            status.setUpdateTime(table.getUpdateTime() / 1000);
+                            status.setCheckTime(lastCheckTime / 1000);
+                            status.setCollation("utf-8");
+                            status.setRows(table.getRowCount());
+                            status.setDataLength(table.getDataLength());
+                            status.setAvgRowLength(table.getAvgRowLength());
+                            tablesResult.add(status);
+                        } finally {
+                            table.readUnlock();
                         }
-                        long lastCheckTime = table.getLastCheckTime() <= 0 ? 0 
: table.getLastCheckTime();
-                        TTableStatus status = new TTableStatus();
-                        status.setName(table.getName());
-                        status.setType(table.getMysqlType());
-                        status.setEngine(table.getEngine());
-                        status.setComment(table.getComment());
-                        status.setCreateTime(table.getCreateTime());
-                        status.setLastCheckTime(lastCheckTime / 1000);
-                        status.setUpdateTime(table.getUpdateTime() / 1000);
-                        status.setCheckTime(lastCheckTime / 1000);
-                        status.setCollation("utf-8");
-                        status.setRows(table.getRowCount());
-                        status.setDataLength(table.getDataLength());
-                        status.setAvgRowLength(table.getAvgRowLength());
-                        tablesResult.add(status);
-                    } finally {
-                        table.readUnlock();
                     }
+                } catch (Exception e) {
+                    LOG.warn("failed to get tables for db {} in catalog {}", 
db.getFullName(), catalogName, e);
                 }
             }
         }
@@ -646,7 +657,6 @@ public class FrontendServiceImpl implements 
FrontendService.Iface {
     public TFeResult updateExportTaskStatus(TUpdateExportTaskStatusRequest 
request) throws TException {
         TStatus status = new TStatus(TStatusCode.OK);
         TFeResult result = new TFeResult(FrontendServiceVersion.V1, status);
-
         return result;
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to