[improvement](http) add show_table_data http api (#28380)

In some cases, users need to get the data size of single replica of a table, and evaluate certain actions based on this, such as estimating the precise backup size.

Signed-off-by: nextdreamblue <zxw520blue1@163.com>
This commit is contained in:
xueweizhang
2023-12-19 11:44:33 +08:00
committed by GitHub
parent ddba98159e
commit d24a1645d9
5 changed files with 402 additions and 0 deletions

View File

@ -54,6 +54,7 @@ public class RestBaseController extends BaseController {
protected static final String LABEL_KEY = "label";
protected static final String TXN_ID_KEY = "txn_id";
protected static final String TXN_OPERATION_KEY = "txn_operation";
protected static final String SINGLE_REPLICA_KEY = "single_replica";
private static final Logger LOG = LogManager.getLogger(RestBaseController.class);
public ActionAuthorizationInfo executeCheckPassword(HttpServletRequest request,

View File

@ -23,6 +23,7 @@ import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.TableIf.TableType;
import org.apache.doris.cluster.ClusterNamespace;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.proc.ProcNodeInterface;
@ -208,6 +209,39 @@ public class ShowAction extends RestBaseController {
return ResponseEntityBuilder.ok(oneEntry);
}
@RequestMapping(path = "/api/show_table_data", method = RequestMethod.GET)
public Object show_table_data(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
checkGlobalAuth(ConnectContext.get().getCurrentUserIdentity(), PrivPredicate.ADMIN);
}
String dbName = request.getParameter(DB_KEY);
String tableName = request.getParameter(TABLE_KEY);
String singleReplica = request.getParameter(SINGLE_REPLICA_KEY);
boolean singleReplicaBool = Boolean.parseBoolean(singleReplica);
Map<String, Map<String, Long>> oneEntry = Maps.newHashMap();
if (dbName != null) {
String fullDbName = getFullDbName(dbName);
DatabaseIf db = Env.getCurrentInternalCatalog().getDbNullable(fullDbName);
if (db == null) {
return ResponseEntityBuilder.okWithCommonError("database " + fullDbName + " not found.");
}
Map<String, Long> tablesEntry = getDataSizeOfTables(db, tableName, singleReplicaBool);
oneEntry.put(ClusterNamespace.getNameFromFullName(fullDbName), tablesEntry);
} else {
for (long dbId : Env.getCurrentInternalCatalog().getDbIds()) {
DatabaseIf db = Env.getCurrentInternalCatalog().getDbNullable(dbId);
if (db == null || !(db instanceof Database) || ((Database) db).isMysqlCompatibleDatabase()) {
continue;
}
Map<String, Long> tablesEntry = getDataSizeOfTables(db, tableName, singleReplicaBool);
oneEntry.put(ClusterNamespace.getNameFromFullName(db.getFullName()), tablesEntry);
}
}
return ResponseEntityBuilder.ok(oneEntry);
}
private Map<String, String> getHaInfo() throws IOException {
HashMap<String, String> feInfo = new HashMap<String, String>();
feInfo.put("role", Env.getCurrentEnv().getFeType().toString());
@ -289,6 +323,46 @@ public class ShowAction extends RestBaseController {
return totalSize;
}
public Map<String, Long> getDataSizeOfTables(DatabaseIf db, String tableName, boolean singleReplica) {
Map<String, Long> oneEntry = Maps.newHashMap();
db.readLock();
try {
if (Strings.isNullOrEmpty(tableName)) {
List<Table> tables = db.getTables();
for (Table table : tables) {
Map<String, Long> tableEntry = getDataSizeOfTable(table, singleReplica);
oneEntry.putAll(tableEntry);
}
} else {
Table table = ((Database) db).getTableNullable(tableName);
if (table == null) {
return oneEntry;
}
Map<String, Long> tableEntry = getDataSizeOfTable(table, singleReplica);
oneEntry.putAll(tableEntry);
}
} finally {
db.readUnlock();
}
return oneEntry;
}
public Map<String, Long> getDataSizeOfTable(Table table, boolean singleReplica) {
Map<String, Long> oneEntry = Maps.newHashMap();
if (table.getType() == TableType.VIEW || table.getType() == TableType.ODBC) {
oneEntry.put(table.getName(), 0L);
} else if (table.getType() == TableType.OLAP) {
table.readLock();
try {
long tableSize = ((OlapTable) table).getDataSize(singleReplica);
oneEntry.put(table.getName(), tableSize);
} finally {
table.readUnlock();
}
}
return oneEntry;
}
private Map<String, Long> getDataSize() {
Map<String, Long> result = new HashMap<String, Long>();
List<String> dbNames = Env.getCurrentInternalCatalog().getDbNames();