This is an automated email from the ASF dual-hosted git repository. morningman 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 8fe5211df4 [improvement](multi-catalog)(cache) invalidate catalog cache when refresh (#14342) 8fe5211df4 is described below commit 8fe5211df46fd61dc1e3472cf7e061c95d2da501 Author: Mingyu Chen <morning...@163.com> AuthorDate: Thu Nov 17 20:47:46 2022 +0800 [improvement](multi-catalog)(cache) invalidate catalog cache when refresh (#14342) Invalidate catalog/db/table cache when doing refresh catalog/db/table. Tested table with 10000 partitions. The refresh operation will cost about 10-20 ms. --- .../{REFRESH-CATALOG.md => REFRESH.md} | 35 ++++++++++++---- docs/sidebars.json | 2 +- .../{REFRESH-CATALOG.md => REFRESH.md} | 33 ++++++++++++--- .../org/apache/doris/catalog/RefreshManager.java | 2 +- .../doris/catalog/external/ExternalDatabase.java | 1 + .../org/apache/doris/datasource/CatalogMgr.java | 4 +- .../apache/doris/datasource/ExternalCatalog.java | 1 + .../doris/datasource/ExternalMetaCacheMgr.java | 36 ++++++++++++++--- .../doris/datasource/ExternalSchemaCache.java | 21 +++++++++- .../doris/datasource/hive/HiveMetaStoreCache.java | 47 ++++++++++++++++++++-- 10 files changed, 155 insertions(+), 27 deletions(-) diff --git a/docs/en/docs/sql-manual/sql-reference/Utility-Statements/REFRESH-CATALOG.md b/docs/en/docs/sql-manual/sql-reference/Utility-Statements/REFRESH.md similarity index 58% rename from docs/en/docs/sql-manual/sql-reference/Utility-Statements/REFRESH-CATALOG.md rename to docs/en/docs/sql-manual/sql-reference/Utility-Statements/REFRESH.md index cbb113c444..6d688f62de 100644 --- a/docs/en/docs/sql-manual/sql-reference/Utility-Statements/REFRESH-CATALOG.md +++ b/docs/en/docs/sql-manual/sql-reference/Utility-Statements/REFRESH.md @@ -1,6 +1,6 @@ --- { - "title": "REFRESH-CATALOG", + "title": "REFRESH", "language": "en" } --- @@ -24,22 +24,28 @@ specific language governing permissions and limitations under the License. --> -## REFRESH-CATALOG +## REFRESH ### Name -REFRESH CATALOG +REFRESH ### Description -This statement is used to refresh the metadata of specific catalog. +This statement refreshes the metadata of the specified Catalog/Database/Table. -Syntax: +syntax: ```sql -REFRESH CATALOG catalog_name +REFRESH CATALOG catalog_name; +REFRESH DATABASE [catalog_name.]database_name; +REFRESH TABLE [catalog_name.][database_name.]table_name; ``` +When the Catalog is refreshed, the object-related Cache is forced to be invalidated. + +Including Partition Cache, Schema Cache, File Cache, etc. + ### Example 1. Refresh hive catalog @@ -48,9 +54,24 @@ REFRESH CATALOG catalog_name REFRESH CATALOG hive; ``` +2. Refresh database1 + + ```sql + REFRESH DATABASE ctl.database1; + REFRESH DATABASE database1; + ``` + +3. Refresh table1 + + ```sql + REFRESH TABLE ctl.db.table1; + REFRESH TABLE db.table1; + REFRESH TABLE table1; + ``` + ### Keywords -REFRESH, CATALOG +REFRESH, CATALOG, DATABASE, TABLE ### Best Practice diff --git a/docs/sidebars.json b/docs/sidebars.json index 5320104bd0..eb3ce2ba7f 100644 --- a/docs/sidebars.json +++ b/docs/sidebars.json @@ -913,7 +913,7 @@ "sql-manual/sql-reference/Utility-Statements/USE", "sql-manual/sql-reference/Utility-Statements/DESCRIBE", "sql-manual/sql-reference/Utility-Statements/SWITCH", - "sql-manual/sql-reference/Utility-Statements/REFRESH-CATALOG" + "sql-manual/sql-reference/Utility-Statements/REFRESH" ] } ] diff --git a/docs/zh-CN/docs/sql-manual/sql-reference/Utility-Statements/REFRESH-CATALOG.md b/docs/zh-CN/docs/sql-manual/sql-reference/Utility-Statements/REFRESH.md similarity index 60% rename from docs/zh-CN/docs/sql-manual/sql-reference/Utility-Statements/REFRESH-CATALOG.md rename to docs/zh-CN/docs/sql-manual/sql-reference/Utility-Statements/REFRESH.md index 77a024cd18..fe7b7b3076 100644 --- a/docs/zh-CN/docs/sql-manual/sql-reference/Utility-Statements/REFRESH-CATALOG.md +++ b/docs/zh-CN/docs/sql-manual/sql-reference/Utility-Statements/REFRESH.md @@ -1,6 +1,6 @@ --- { - "title": "REFRESH-CATALOG", + "title": "REFRESH", "language": "zh-CN" } --- @@ -24,22 +24,28 @@ specific language governing permissions and limitations under the License. --> -## REFRESH-CATALOG +## REFRESH ### Name -REFRESH CATALOG +REFRESH ### Description -该语句用于刷新指定 Catalog 的元数据。 +该语句用于刷新指定 Catalog/Database/Table 的元数据。 语法: ```sql -REFRESH CATALOG catalog_name +REFRESH CATALOG catalog_name; +REFRESH DATABASE [catalog_name.]database_name; +REFRESH TABLE [catalog_name.][database_name.]table_name; ``` +刷新Catalog的同时,会强制使对象相关的 Cache 失效。 + +包括Partition Cache、Schema Cache、File Cache等。 + ### Example 1. 刷新 hive catalog @@ -48,9 +54,24 @@ REFRESH CATALOG catalog_name REFRESH CATALOG hive; ``` +2. 刷新 database1 + + ```sql + REFRESH DATABASE ctl.database1; + REFRESH DATABASE database1; + ``` + +3. 刷新 table1 + + ```sql + REFRESH TABLE ctl.db.table1; + REFRESH TABLE db.table1; + REFRESH TABLE table1; + ``` + ### Keywords -REFRESH, CATALOG +REFRESH, CATALOG, DATABASE, TABLE ### Best Practice diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/RefreshManager.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/RefreshManager.java index 439c8c73c8..558b133f8c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/RefreshManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/RefreshManager.java @@ -159,7 +159,7 @@ public class RefreshManager { if (table == null) { throw new DdlException("Table " + tableName + " does not exist in db " + dbName); } - Env.getCurrentEnv().getExtMetaCacheMgr().removeCache(catalog.getId(), dbName, tableName); + Env.getCurrentEnv().getExtMetaCacheMgr().invalidateTableCache(catalog.getId(), dbName, tableName); ExternalObjectLog log = new ExternalObjectLog(); log.setCatalogId(catalog.getId()); log.setDbId(db.getId()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/external/ExternalDatabase.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/external/ExternalDatabase.java index ffbbda4a46..820360c21d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/external/ExternalDatabase.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/external/ExternalDatabase.java @@ -95,6 +95,7 @@ public class ExternalDatabase<T extends ExternalTable> implements DatabaseIf<T>, public void setUnInitialized() { this.initialized = false; + Env.getCurrentEnv().getExtMetaCacheMgr().invalidateDbCache(extCatalog.getId(), name); } public boolean isInitialized() { diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java index 39ec822f6a..ee879adf24 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java @@ -439,8 +439,8 @@ public class CatalogMgr implements Writable, GsonPostProcessable { ExternalCatalog catalog = (ExternalCatalog) idToCatalog.get(log.getCatalogId()); ExternalDatabase db = catalog.getDbForReplay(log.getDbId()); ExternalTable table = db.getTableForReplay(log.getTableId()); - Env.getCurrentEnv().getExtMetaCacheMgr().getSchemaCache(catalog) - .invalidateCache(db.getFullName(), table.getName()); + Env.getCurrentEnv().getExtMetaCacheMgr() + .invalidateTableCache(catalog.getId(), db.getFullName(), table.getName()); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java index 385c85fadf..d50b4d39e5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java @@ -130,6 +130,7 @@ public abstract class ExternalCatalog implements CatalogIf<ExternalDatabase>, Wr public void setUninitialized() { this.initialized = false; + Env.getCurrentEnv().getExtMetaCacheMgr().invalidateCatalogCache(id); } public ExternalDatabase getDbForReplay(long dbId) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalMetaCacheMgr.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalMetaCacheMgr.java index eb9123f814..934c3f8bbe 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalMetaCacheMgr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalMetaCacheMgr.java @@ -17,6 +17,7 @@ package org.apache.doris.datasource; +import org.apache.doris.cluster.ClusterNamespace; import org.apache.doris.common.ThreadPoolManager; import org.apache.doris.datasource.hive.HiveMetaStoreCache; @@ -80,16 +81,41 @@ public class ExternalMetaCacheMgr { } } - public void removeCache(long catalogId, String dbName, String tblName) { + public void invalidateTableCache(long catalogId, String dbName, String tblName) { + dbName = ClusterNamespace.getNameFromFullName(dbName); ExternalSchemaCache schemaCache = schemaCacheMap.get(catalogId); if (schemaCache != null) { - schemaCache.invalidateCache(dbName, tblName); - LOG.debug("invalid schema cache for {}.{} in catalog {}", dbName, tblName, catalogId); + schemaCache.invalidateTableCache(dbName, tblName); } HiveMetaStoreCache metaCache = cacheMap.get(catalogId); if (metaCache != null) { - metaCache.invalidateCache(dbName, tblName); - LOG.debug("invalid meta cache for {}.{} in catalog {}", dbName, tblName, catalogId); + metaCache.invalidateTableCache(dbName, tblName); } + LOG.debug("invalid table cache for {}.{} in catalog {}", dbName, tblName, catalogId); + } + + public void invalidateDbCache(long catalogId, String dbName) { + dbName = ClusterNamespace.getNameFromFullName(dbName); + ExternalSchemaCache schemaCache = schemaCacheMap.get(catalogId); + if (schemaCache != null) { + schemaCache.invalidateDbCache(dbName); + } + HiveMetaStoreCache metaCache = cacheMap.get(catalogId); + if (metaCache != null) { + metaCache.invalidateDbCache(dbName); + } + LOG.debug("invalid db cache for {} in catalog {}", dbName, catalogId); + } + + public void invalidateCatalogCache(long catalogId) { + ExternalSchemaCache schemaCache = schemaCacheMap.get(catalogId); + if (schemaCache != null) { + schemaCache.invalidateAll(); + } + HiveMetaStoreCache metaCache = cacheMap.get(catalogId); + if (metaCache != null) { + metaCache.invalidateAll(); + } + LOG.debug("invalid catalog cache for {}", catalogId); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalSchemaCache.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalSchemaCache.java index 718525ae6a..1e4800ee81 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalSchemaCache.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalSchemaCache.java @@ -34,6 +34,7 @@ import org.apache.logging.log4j.Logger; import java.util.List; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -92,9 +93,27 @@ public class ExternalSchemaCache { } } - public void invalidateCache(String dbName, String tblName) { + public void invalidateTableCache(String dbName, String tblName) { SchemaCacheKey key = new SchemaCacheKey(dbName, tblName); schemaCache.invalidate(key); + LOG.debug("invalid schema cache for {}.{} in catalog {}", dbName, tblName, catalog.getName()); + } + + public void invalidateDbCache(String dbName) { + long start = System.currentTimeMillis(); + Set<SchemaCacheKey> keys = schemaCache.asMap().keySet(); + for (SchemaCacheKey key : keys) { + if (key.dbName.equals(dbName)) { + schemaCache.invalidate(key); + } + } + LOG.debug("invalid schema cache for db {} in catalog {} cost: {} ms", dbName, catalog.getName(), + (System.currentTimeMillis() - start)); + } + + public void invalidateAll() { + schemaCache.invalidateAll(); + LOG.debug("invalid all schema cache in catalog {}", catalog.getName()); } @Data diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java index ddcc12d5fc..ebb82b8363 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java @@ -60,6 +60,7 @@ import org.apache.logging.log4j.Logger; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -327,10 +328,43 @@ public class HiveMetaStoreCache { return partitions; } - public void invalidateCache(String dbName, String tblName) { + public void invalidateTableCache(String dbName, String tblName) { PartitionValueCacheKey key = new PartitionValueCacheKey(dbName, tblName, null); - partitionValuesCache.invalidate(key); - // TODO: find a way to invalidate partitionCache and fileCache + HivePartitionValues partitionValues = partitionValuesCache.getIfPresent(key); + if (partitionValues != null) { + long start = System.currentTimeMillis(); + for (List<String> values : partitionValues.partitionValuesMap.values()) { + PartitionCacheKey partKey = new PartitionCacheKey(dbName, tblName, values); + HivePartition partition = partitionCache.getIfPresent(partKey); + if (partition != null) { + fileCache.invalidate(new FileCacheKey(partition.getPath(), null)); + partitionCache.invalidate(partKey); + } + } + partitionValuesCache.invalidate(key); + LOG.debug("invalid table cache for {}.{} in catalog {}, cache num: {}, cost: {} ms", + dbName, tblName, catalog.getName(), partitionValues.partitionValuesMap.size(), + (System.currentTimeMillis() - start)); + } + } + + public void invalidateDbCache(String dbName) { + long start = System.currentTimeMillis(); + Set<PartitionValueCacheKey> keys = partitionValuesCache.asMap().keySet(); + for (PartitionValueCacheKey key : keys) { + if (key.dbName.equals(dbName)) { + invalidateTableCache(dbName, key.tblName); + } + } + LOG.debug("invalid db cache for {} in catalog {}, cache num: {}, cost: {} ms", dbName, catalog.getName(), + keys.size(), (System.currentTimeMillis() - start)); + } + + public void invalidateAll() { + partitionValuesCache.invalidateAll(); + partitionCache.invalidateAll(); + fileCache.invalidateAll(); + LOG.debug("invalid all meta cache in catalog {}", catalog.getName()); } /** @@ -444,7 +478,8 @@ public class HiveMetaStoreCache { @Data public static class HivePartitionValues { - private Map<Long, PartitionItem> idToPartitionItem = Maps.newHashMap(); + private Map<Long, PartitionItem> idToPartitionItem; + private Map<Long, List<String>> partitionValuesMap = Maps.newHashMap(); private Map<UniqueId, Range<PartitionKey>> uidToPartitionRange; private Map<Range<PartitionKey>, UniqueId> rangeToId; private RangeMap<ColumnBound, UniqueId> singleColumnRangeMap; @@ -454,6 +489,10 @@ public class HiveMetaStoreCache { Map<Range<PartitionKey>, UniqueId> rangeToId, RangeMap<ColumnBound, UniqueId> singleColumnRangeMap) { this.idToPartitionItem = idToPartitionItem; + for (Map.Entry<Long, PartitionItem> entry : this.idToPartitionItem.entrySet()) { + partitionValuesMap.put(entry.getKey(), + ((ListPartitionItem) entry.getValue()).getItems().get(0).getPartitionValuesAsStringList()); + } this.uidToPartitionRange = uidToPartitionRange; this.rangeToId = rangeToId; this.singleColumnRangeMap = singleColumnRangeMap; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org