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

dataroaring 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 7c8bcd51bb8 [improve](catalog recycle bin) show data size info when 
show catalog recycle bin (#30592)
7c8bcd51bb8 is described below

commit 7c8bcd51bb8fb988005c4560847c45cdaed67894
Author: meiyi <myime...@gmail.com>
AuthorDate: Thu Feb 1 14:44:23 2024 +0800

    [improve](catalog recycle bin) show data size info when show catalog 
recycle bin (#30592)
---
 .../doris/analysis/ShowCatalogRecycleBinStmt.java  |   2 +-
 .../apache/doris/catalog/CatalogRecycleBin.java    |  90 +++++++++----
 .../data/catalog_recycle_bin_p0/all_types.csv.gz   | Bin 0 -> 6817 bytes
 .../org/apache/doris/regression/suite/Suite.groovy |  23 ++++
 .../suites/catalog_recycle_bin_p0/show.groovy      | 146 +++++++++++++++++++++
 .../correctness_p0/test_bugfix_block_reuse.groovy  |   3 -
 .../correctness_p0/test_many_inlineview.groovy     |   3 -
 7 files changed, 236 insertions(+), 31 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java
 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java
index a2ee6360a89..fe241acf047 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java
@@ -34,7 +34,7 @@ import java.util.function.Predicate;
 public class ShowCatalogRecycleBinStmt extends ShowStmt {
     public static final ImmutableList<String> TITLE_NAMES = new 
ImmutableList.Builder<String>()
             
.add("Type").add("Name").add("DbId").add("TableId").add("PartitionId").add("DropTime")
-            .build();
+            .add("DataSize").add("RemoteDataSize").build();
 
     private Expr where;
     private String nameValue;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java
index 5eaa18f2bf8..50cc2679251 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java
@@ -23,8 +23,10 @@ import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.FeConstants;
 import org.apache.doris.common.FeMetaVersion;
+import org.apache.doris.common.Pair;
 import org.apache.doris.common.io.Text;
 import org.apache.doris.common.io.Writable;
+import org.apache.doris.common.util.DebugUtil;
 import org.apache.doris.common.util.DynamicPartitionUtil;
 import org.apache.doris.common.util.MasterDaemon;
 import org.apache.doris.common.util.RangeUtils;
@@ -48,6 +50,7 @@ import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -980,30 +983,7 @@ public class CatalogRecycleBin extends MasterDaemon 
implements Writable {
     }
 
     public List<List<String>> getInfo() {
-        List<List<String>> dbInfos = Lists.newArrayList();
-        for (Map.Entry<Long, RecycleDatabaseInfo> entry : 
idToDatabase.entrySet()) {
-            List<String> info = Lists.newArrayList();
-            info.add("Database");
-            RecycleDatabaseInfo dbInfo = entry.getValue();
-            Database db = dbInfo.getDb();
-            info.add(db.getFullName());
-            info.add(String.valueOf(entry.getKey()));
-            info.add("");
-            info.add("");
-            //info.add(String.valueOf(idToRecycleTime.get(entry.getKey())));
-            
info.add(TimeUtils.longToTimeString(idToRecycleTime.get(entry.getKey())));
-
-            dbInfos.add(info);
-        }
-        // sort by Name, DropTime
-        dbInfos.sort((x, y) -> {
-            int nameRet = x.get(1).compareTo(y.get(1));
-            if (nameRet == 0) {
-                return x.get(5).compareTo(y.get(5));
-            } else {
-                return nameRet;
-            }
-        });
+        Map<Long, Pair<Long, Long>> dbToDataSize = new HashMap<>();
 
         List<List<String>> tableInfos = Lists.newArrayList();
         for (Map.Entry<Long, RecycleTableInfo> entry : idToTable.entrySet()) {
@@ -1017,6 +997,22 @@ public class CatalogRecycleBin extends MasterDaemon 
implements Writable {
             info.add("");
             //info.add(String.valueOf(idToRecycleTime.get(entry.getKey())));
             
info.add(TimeUtils.longToTimeString(idToRecycleTime.get(entry.getKey())));
+            // data size
+            long dataSize = table.getDataSize(false);
+            info.add(DebugUtil.printByteWithUnit(dataSize));
+            // remote data size
+            long remoteDataSize = table instanceof OlapTable ? ((OlapTable) 
table).getRemoteDataSize() : 0L;
+            info.add(DebugUtil.printByteWithUnit(remoteDataSize));
+            // calculate database data size
+            dbToDataSize.compute(tableInfo.getDbId(), (k, v) -> {
+                if (v == null) {
+                    return Pair.of(dataSize, remoteDataSize);
+                } else {
+                    v.first += dataSize;
+                    v.second += remoteDataSize;
+                    return v;
+                }
+            });
 
             tableInfos.add(info);
         }
@@ -1042,6 +1038,22 @@ public class CatalogRecycleBin extends MasterDaemon 
implements Writable {
             info.add(String.valueOf(entry.getKey()));
             //info.add(String.valueOf(idToRecycleTime.get(entry.getKey())));
             
info.add(TimeUtils.longToTimeString(idToRecycleTime.get(entry.getKey())));
+            // data size
+            long dataSize = partition.getDataSize(false);
+            info.add(DebugUtil.printByteWithUnit(dataSize));
+            // remote data size
+            long remoteDataSize = partition.getRemoteDataSize();
+            info.add(DebugUtil.printByteWithUnit(remoteDataSize));
+            // calculate database data size
+            dbToDataSize.compute(partitionInfo.getDbId(), (k, v) -> {
+                if (v == null) {
+                    return Pair.of(dataSize, remoteDataSize);
+                } else {
+                    v.first += dataSize;
+                    v.second += remoteDataSize;
+                    return v;
+                }
+            });
 
             partitionInfos.add(info);
         }
@@ -1055,6 +1067,36 @@ public class CatalogRecycleBin extends MasterDaemon 
implements Writable {
             }
         });
 
+        List<List<String>> dbInfos = Lists.newArrayList();
+        for (Map.Entry<Long, RecycleDatabaseInfo> entry : 
idToDatabase.entrySet()) {
+            List<String> info = Lists.newArrayList();
+            info.add("Database");
+            RecycleDatabaseInfo dbInfo = entry.getValue();
+            Database db = dbInfo.getDb();
+            info.add(db.getFullName());
+            info.add(String.valueOf(entry.getKey()));
+            info.add("");
+            info.add("");
+            //info.add(String.valueOf(idToRecycleTime.get(entry.getKey())));
+            
info.add(TimeUtils.longToTimeString(idToRecycleTime.get(entry.getKey())));
+            // data size
+            Pair<Long, Long> dataSizePair = 
dbToDataSize.getOrDefault(entry.getKey(), Pair.of(0L, 0L));
+            info.add(DebugUtil.printByteWithUnit(dataSizePair.first));
+            // remote data size
+            info.add(DebugUtil.printByteWithUnit(dataSizePair.second));
+
+            dbInfos.add(info);
+        }
+        // sort by Name, DropTime
+        dbInfos.sort((x, y) -> {
+            int nameRet = x.get(1).compareTo(y.get(1));
+            if (nameRet == 0) {
+                return x.get(5).compareTo(y.get(5));
+            } else {
+                return nameRet;
+            }
+        });
+
         return Stream.of(dbInfos, tableInfos, 
partitionInfos).flatMap(Collection::stream).collect(Collectors.toList());
     }
 
diff --git a/regression-test/data/catalog_recycle_bin_p0/all_types.csv.gz 
b/regression-test/data/catalog_recycle_bin_p0/all_types.csv.gz
new file mode 100644
index 00000000000..b2bff00cd6c
Binary files /dev/null and 
b/regression-test/data/catalog_recycle_bin_p0/all_types.csv.gz differ
diff --git 
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
 
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
index 96b97c17046..ef4a459485e 100644
--- 
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
+++ 
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
@@ -400,6 +400,20 @@ class Suite implements GroovyInterceptable {
         }
     }
 
+    long getTableId(String dbName, String tableName) {
+        def dbInfo = sql "show proc '/dbs'"
+        for(List<Object> row : dbInfo) {
+            if (row[1].equals(dbName)) {
+                def tbInfo = sql "show proc '/dbs/${row[0]}' "
+                for (List<Object> tb : tbInfo) {
+                    if (tb[1].equals(tableName)) {
+                        return tb[0].toLong()
+                    }
+                }
+            }
+        }
+    }
+
     long getDbId() {
         def dbInfo = sql "show proc '/dbs'"
         for(List<Object> row : dbInfo) {
@@ -410,6 +424,15 @@ class Suite implements GroovyInterceptable {
         }
     }
 
+    long getDbId(String dbName) {
+        def dbInfo = sql "show proc '/dbs'"
+        for (List<Object> row : dbInfo) {
+            if (row[1].equals(dbName)) {
+                return row[0].toLong()
+            }
+        }
+    }
+
     long getTableVersion(long dbId, String tableName) {
        def result = sql_return_maparray """show proc '/dbs/${dbId}'"""
         for (def res : result) {
diff --git a/regression-test/suites/catalog_recycle_bin_p0/show.groovy 
b/regression-test/suites/catalog_recycle_bin_p0/show.groovy
new file mode 100644
index 00000000000..2f929f0216f
--- /dev/null
+++ b/regression-test/suites/catalog_recycle_bin_p0/show.groovy
@@ -0,0 +1,146 @@
+// 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.
+
+suite("show") {
+    def dbs = [
+            'regression_test_catalog_recycle_bin_db0',
+            'regression_test_catalog_recycle_bin_db1',
+            'regression_test_catalog_recycle_bin_db2'
+    ]
+    def dbIds = []
+
+    for (def db : dbs) {
+        sql """ drop database if exists $db """
+        sql """ create database $db """
+        dbIds.add(getDbId(db) + '')
+    }
+
+    def tables = [
+            [dbs[1], 'show0'],
+            [dbs[1], 'show1'],
+            [dbs[2], 'show2'],
+            [dbs[2], 'show3'],
+            [dbs[2], 'show4']
+    ]
+    def tableIds = []
+
+    for (def entry in tables) {
+        def dbName = entry[0]
+        def tableName = entry[1]
+        sql """
+            CREATE TABLE IF NOT EXISTS $dbName.$tableName (
+                `k1` int(11) NULL,
+                `k2` tinyint(4) NULL,
+                `k3` smallint(6) NULL,
+                `k4` bigint(20) NULL,
+                `k5` largeint(40) NULL,
+                `k6` float NULL,
+                `k7` double NULL,
+                `k8` decimal(9, 0) NULL,
+                `k9` char(10) NULL,
+                `k10` varchar(1024) NULL,
+                `k11` text NULL,
+                `k12` date NULL,
+                `k13` datetime NULL
+            ) ENGINE=OLAP
+            PARTITION BY RANGE(k1)
+            (
+                PARTITION p2000 VALUES LESS THAN ('2000'),
+                PARTITION p5000 VALUES LESS THAN ('5000')
+            )
+            DISTRIBUTED BY HASH(`k1`) BUCKETS 3
+            PROPERTIES (
+                "replication_allocation" = "tag.location.default: 1"
+            );
+        """
+        tableIds.add(getTableId(dbName, tableName) + '')
+
+        streamLoad {
+            db "${dbName}"
+            table "${tableName}"
+
+            set 'column_separator', ','
+            set 'compress_type', 'gz'
+
+            file 'all_types.csv.gz'
+            time 10000 // limit inflight 10s
+
+            check { result, exception, startTime, endTime ->
+                if (exception != null) {
+                    throw exception
+                }
+                log.info("Stream load result: ${result}".toString())
+                def json = parseJson(result)
+                assertEquals("success", json.Status.toLowerCase())
+                assertEquals(2500, json.NumberTotalRows)
+                assertEquals(0, json.NumberFilteredRows)
+            }
+        }
+    }
+
+    logger.info("dbIds: " + dbIds)
+    logger.info("tableIds: " + tableIds)
+
+    sql """ drop database ${dbs[0]} """
+    sql """ drop database ${dbs[1]} """
+    sql """ drop table ${tables[2][0]}.${tables[2][1]} """
+    sql """ alter table ${tables[3][0]}.${tables[3][1]} drop partition p2000 
"""
+
+    def checkShowResults = () -> {
+        def results = sql_return_maparray """ show catalog recycle bin """
+        // logger.info("show catalog recycle bin result: " + results)
+        def recycleBinSize = 0
+        for (final def result in results) {
+            logger.info("result: " + result)
+            if (result.DbId == dbIds[0] && result.TableId == '') { // db0 is 
dropped
+                assertEquals(result['DataSize'], '0.000 ')
+                assertEquals(result['RemoteDataSize'], '0.000 ')
+                recycleBinSize++
+            } else if (result.DbId == dbIds[1] && result.TableId == '') { // 
db1 is dropped
+                assertTrue(result['DataSize'].startsWith('44') && 
result['DataSize'].contains('KB'))
+                assertEquals(result['RemoteDataSize'], '0.000 ')
+                recycleBinSize++
+            } else if (result.TableId == tableIds[2]) { // table2 is dropped
+                assertEquals(result['PartitionId'], '')
+                assertTrue(result['DataSize'].startsWith('22') && 
result['DataSize'].contains('KB'))
+                assertEquals(result['RemoteDataSize'], '0.000 ')
+                recycleBinSize++
+            } else if (result.TableId == tableIds[3]) { // the partition of 
table3 is dropped
+                assertFalse(result['PartitionId'].isEmpty())
+                assertTrue(result['DataSize'].startsWith('12') && 
result['DataSize'].contains('KB'))
+                assertEquals(result['RemoteDataSize'], '0.000 ')
+                recycleBinSize++
+            }
+        }
+        assertEquals(4, recycleBinSize)
+    }
+
+    for (def i = 0; i < 20; ++i) {
+        try {
+            logger.info("round " + i)
+            checkShowResults()
+            break
+        } catch (Throwable e) {
+            if (i == 9) {
+                throw e
+            } else {
+                // wait for the data size report
+                sleep(10000)
+            }
+        }
+    }
+}
diff --git 
a/regression-test/suites/correctness_p0/test_bugfix_block_reuse.groovy 
b/regression-test/suites/correctness_p0/test_bugfix_block_reuse.groovy
index fb25cd7e687..5423a95d786 100644
--- a/regression-test/suites/correctness_p0/test_bugfix_block_reuse.groovy
+++ b/regression-test/suites/correctness_p0/test_bugfix_block_reuse.groovy
@@ -15,9 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-// Test some keywords that may conflict.
-// For example, "bin" is used for function "bin",
-// and also used "show catalog recycle bin"
 suite("test_bugfix_block_reuse") {
     sql "drop table if exists test_bugfix_block_reuse;"
     sql """
diff --git a/regression-test/suites/correctness_p0/test_many_inlineview.groovy 
b/regression-test/suites/correctness_p0/test_many_inlineview.groovy
index 810144947cb..5c46457f411 100644
--- a/regression-test/suites/correctness_p0/test_many_inlineview.groovy
+++ b/regression-test/suites/correctness_p0/test_many_inlineview.groovy
@@ -15,9 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-// Test some keywords that may conflict.
-// For example, "bin" is used for function "bin",
-// and also used "show catalog recycle bin"
 suite("test_many_inlineview") {
     sql """
         drop table if exists ods_drp_ch_sys_codelist_et;


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

Reply via email to