[feature](stmt) add ADMIN COPY TABLET stmt for local debug (#12176)
Add a new stmt ADMIN COPY TABLET for easy copy a tablet to local env to reproduce problem. See document for more details.
This commit is contained in:
@ -243,7 +243,7 @@ terminal String KW_ADD, KW_ADMIN, KW_AFTER, KW_AGGREGATE, KW_ALIAS, KW_ALL, KW_A
|
||||
KW_BACKEND, KW_BACKUP, KW_BETWEEN, KW_BEGIN, KW_BIGINT, KW_BINLOG, KW_BITMAP, KW_BITMAP_UNION, KW_QUANTILE_STATE, KW_QUANTILE_UNION, KW_BLOB, KW_BOOLEAN, KW_BROKER, KW_BACKENDS, KW_BY, KW_BUILD, KW_BUILTIN,
|
||||
KW_CANCEL, KW_CASE, KW_CAST, KW_CHAIN, KW_CHAR, KW_CHARSET, KW_CHECK, KW_CLUSTER, KW_CLUSTERS, KW_CLEAN, KW_CURRENT_TIMESTAMP,
|
||||
KW_COLLATE, KW_COLLATION, KW_COLUMN, KW_COLUMNS, KW_COMMENT, KW_COMMIT, KW_COMMITTED, KW_COMPACT, KW_COMPLETE,
|
||||
KW_CONFIG, KW_CONNECTION, KW_CONNECTION_ID, KW_CONSISTENT, KW_CONVERT, KW_COUNT, KW_CREATE, KW_CREATION, KW_CROSS, KW_CUBE, KW_CURRENT, KW_CURRENT_USER,
|
||||
KW_CONFIG, KW_CONNECTION, KW_CONNECTION_ID, KW_CONSISTENT, KW_CONVERT, KW_COPY, KW_COUNT, KW_CREATE, KW_CREATION, KW_CROSS, KW_CUBE, KW_CURRENT, KW_CURRENT_USER,
|
||||
KW_DATA, KW_DATABASE, KW_DATABASES, KW_DATE, KW_DATETIME, KW_DATEV2, KW_DATETIMEV2, KW_DAY, KW_DECIMAL, KW_DECIMALV3, KW_DECOMMISSION, KW_DEFAULT, KW_DEFERRED, KW_DEMAND, KW_DESC, KW_DESCRIBE,
|
||||
KW_DELETE, KW_UPDATE, KW_DIAGNOSE, KW_DISK, KW_DISTINCT, KW_DISTINCTPC, KW_DISTINCTPCSA, KW_DISTRIBUTED, KW_DISTRIBUTION, KW_DYNAMIC, KW_BUCKETS, KW_DIV, KW_DOUBLE, KW_DROP, KW_DROPP, KW_DUPLICATE,
|
||||
KW_ELSE, KW_ENABLE, KW_ENCRYPTKEY, KW_ENCRYPTKEYS, KW_END, KW_ENGINE, KW_ENGINES, KW_ENTER, KW_ERRORS, KW_EVENTS, KW_EXCEPT, KW_EXCLUDE,
|
||||
@ -5624,6 +5624,10 @@ admin_stmt ::=
|
||||
{:
|
||||
RESULT = new AdminShowTabletStorageFormatStmt(true);
|
||||
:}
|
||||
| KW_ADMIN KW_COPY KW_TABLET INTEGER_LITERAL:tabletId opt_properties:properties
|
||||
{:
|
||||
RESULT = new AdminCopyTabletStmt(tabletId, properties);
|
||||
:}
|
||||
;
|
||||
|
||||
truncate_stmt ::=
|
||||
@ -5797,6 +5801,8 @@ keyword ::=
|
||||
{: RESULT = id; :}
|
||||
| KW_CONVERT:id
|
||||
{: RESULT = id; :}
|
||||
| KW_COPY:id
|
||||
{: RESULT = id; :}
|
||||
| KW_CREATION:id
|
||||
{: RESULT = id; :}
|
||||
| KW_DATA:id
|
||||
|
||||
@ -0,0 +1,120 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.doris.analysis;
|
||||
|
||||
import org.apache.doris.catalog.Column;
|
||||
import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
import org.apache.doris.qe.ShowResultSetMetaData;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
// ADMIN COPY TABLET 10110 PROPERTIES('version' = '1000', backend_id = '10001');
|
||||
public class AdminCopyTabletStmt extends ShowStmt {
|
||||
public static final String PROP_VERSION = "version";
|
||||
public static final String PROP_BACKEND_ID = "backend_id";
|
||||
public static final String PROP_EXPIRATION = "expiration_minutes";
|
||||
private static final long DEFAULT_EXPIRATION_MINUTES = 60;
|
||||
public static final ImmutableList<String> TITLE_NAMES = new ImmutableList.Builder<String>().add("TabletId")
|
||||
.add("BackendId").add("Ip").add("Path").add("ExpirationMinutes").add("CreateTableStmt").build();
|
||||
|
||||
private long tabletId;
|
||||
private Map<String, String> properties = Maps.newHashMap();
|
||||
private long version = -1;
|
||||
private long backendId = -1;
|
||||
private long expirationMinutes = DEFAULT_EXPIRATION_MINUTES; // default 60min
|
||||
|
||||
public AdminCopyTabletStmt(long tabletId, Map<String, String> properties) {
|
||||
this.tabletId = tabletId;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public long getTabletId() {
|
||||
return tabletId;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public long getBackendId() {
|
||||
return backendId;
|
||||
}
|
||||
|
||||
public long getExpirationMinutes() {
|
||||
return expirationMinutes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void analyze(Analyzer analyzer) throws AnalysisException {
|
||||
if (!Env.getCurrentEnv().getAuth().checkGlobalPriv(ConnectContext.get(), PrivPredicate.OPERATOR)) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "NODE");
|
||||
}
|
||||
|
||||
try {
|
||||
Iterator<Map.Entry<String, String>> iter = properties.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<String, String> entry = iter.next();
|
||||
if (entry.getKey().equalsIgnoreCase(PROP_VERSION)) {
|
||||
version = Long.valueOf(entry.getValue());
|
||||
iter.remove();
|
||||
continue;
|
||||
} else if (entry.getKey().equalsIgnoreCase(PROP_BACKEND_ID)) {
|
||||
backendId = Long.valueOf(entry.getValue());
|
||||
iter.remove();
|
||||
continue;
|
||||
} else if (entry.getKey().equalsIgnoreCase(PROP_EXPIRATION)) {
|
||||
expirationMinutes = Long.valueOf(entry.getValue());
|
||||
expirationMinutes = Math.min(DEFAULT_EXPIRATION_MINUTES, expirationMinutes);
|
||||
iter.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new AnalysisException("Invalid property: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (!properties.isEmpty()) {
|
||||
throw new AnalysisException("Unknown property: " + properties);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShowResultSetMetaData getMetaData() {
|
||||
ShowResultSetMetaData.Builder builder = ShowResultSetMetaData.builder();
|
||||
for (String title : TITLE_NAMES) {
|
||||
builder.addColumn(new Column(title, ScalarType.createStringType()));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedirectStatus getRedirectStatus() {
|
||||
return RedirectStatus.NO_FORWARD;
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +74,6 @@ import org.apache.doris.analysis.ReplacePartitionClause;
|
||||
import org.apache.doris.analysis.RestoreStmt;
|
||||
import org.apache.doris.analysis.RollupRenameClause;
|
||||
import org.apache.doris.analysis.ShowAlterStmt.AlterType;
|
||||
import org.apache.doris.analysis.TableName;
|
||||
import org.apache.doris.analysis.TableRenameClause;
|
||||
import org.apache.doris.analysis.TruncateTableStmt;
|
||||
import org.apache.doris.analysis.UninstallPluginStmt;
|
||||
@ -2683,9 +2682,9 @@ public class Env {
|
||||
}
|
||||
|
||||
public static void getDdlStmt(TableIf table, List<String> createTableStmt, List<String> addPartitionStmt,
|
||||
List<String> createRollupStmt, boolean separatePartition, boolean hidePassword) {
|
||||
List<String> createRollupStmt, boolean separatePartition, boolean hidePassword, long specificVersion) {
|
||||
getDdlStmt(null, null, table, createTableStmt, addPartitionStmt, createRollupStmt, separatePartition,
|
||||
hidePassword, false);
|
||||
hidePassword, false, specificVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2695,7 +2694,7 @@ public class Env {
|
||||
*/
|
||||
public static void getDdlStmt(DdlStmt ddlStmt, String dbName, TableIf table, List<String> createTableStmt,
|
||||
List<String> addPartitionStmt, List<String> createRollupStmt, boolean separatePartition,
|
||||
boolean hidePassword, boolean getDdlForLike) {
|
||||
boolean hidePassword, boolean getDdlForLike, long specificVersion) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// 1. create table
|
||||
@ -2764,6 +2763,17 @@ public class Env {
|
||||
}
|
||||
sb.append(Joiner.on(", ").join(keysColumnNames)).append(")");
|
||||
|
||||
if (specificVersion != -1) {
|
||||
// for copy tablet operation
|
||||
sb.append("\nDISTRIBUTED BY HASH(").append(olapTable.getBaseSchema().get(0).getName())
|
||||
.append(") BUCKETS 1");
|
||||
sb.append("\nPROPERTIES (\n" + "\"replication_num\" = \"1\",\n" + "\"version_info\" = \""
|
||||
+ specificVersion + "\"\n" + ")");
|
||||
createTableStmt.add(sb + ";");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
addTableComment(olapTable, sb);
|
||||
|
||||
// partition
|
||||
@ -5007,15 +5017,4 @@ public class Env {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public TableName getTableNameByTableId(Long tableId) {
|
||||
for (String dbName : getInternalCatalog().getDbNames()) {
|
||||
DatabaseIf db = getInternalCatalog().getDbNullable(dbName);
|
||||
Optional<Table> table = db.getTable(tableId);
|
||||
if (table.isPresent()) {
|
||||
return new TableName(InternalCatalog.INTERNAL_CATALOG_NAME, db.getFullName(), table.get().getName());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1084,7 +1084,7 @@ public class InternalCatalog implements CatalogIf<Database> {
|
||||
throw new DdlException("Table[" + table.getName() + "] is external, not support rollup copy");
|
||||
}
|
||||
|
||||
Env.getDdlStmt(stmt, stmt.getDbName(), table, createTableStmt, null, null, false, false, true);
|
||||
Env.getDdlStmt(stmt, stmt.getDbName(), table, createTableStmt, null, null, false, false, true, -1L);
|
||||
if (createTableStmt.isEmpty()) {
|
||||
ErrorReport.reportDdlException(ErrorCode.ERROR_CREATE_TABLE_LIKE_EMPTY, "CREATE");
|
||||
}
|
||||
@ -1588,6 +1588,7 @@ public class InternalCatalog implements CatalogIf<Database> {
|
||||
// version and version hash
|
||||
if (versionInfo != null) {
|
||||
partition.updateVisibleVersion(versionInfo);
|
||||
partition.setNextVersion(versionInfo + 1);
|
||||
}
|
||||
long version = partition.getVisibleVersion();
|
||||
|
||||
|
||||
@ -76,8 +76,8 @@ public class GetDdlStmtAction extends RestBaseController {
|
||||
|
||||
table.readLock();
|
||||
try {
|
||||
Env.getDdlStmt(table, createTableStmt, addPartitionStmt,
|
||||
createRollupStmt, true, false /* show password */);
|
||||
Env.getDdlStmt(table, createTableStmt, addPartitionStmt, createRollupStmt, true, false /* show password */,
|
||||
-1L);
|
||||
} finally {
|
||||
table.readUnlock();
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ public class StmtExecutionAction extends RestBaseController {
|
||||
List<String> createStmts = Lists.newArrayList();
|
||||
for (TableIf tbl : tableMap.values()) {
|
||||
List<String> createTableStmts = Lists.newArrayList();
|
||||
Env.getDdlStmt(tbl, createTableStmts, null, null, false, true);
|
||||
Env.getDdlStmt(tbl, createTableStmts, null, null, false, true, -1L);
|
||||
if (!createTableStmts.isEmpty()) {
|
||||
createStmts.add(createTableStmts.get(0));
|
||||
}
|
||||
|
||||
@ -541,10 +541,14 @@ public class MasterImpl {
|
||||
|
||||
private void finishMakeSnapshot(AgentTask task, TFinishTaskRequest request) {
|
||||
SnapshotTask snapshotTask = (SnapshotTask) task;
|
||||
if (Env.getCurrentEnv().getBackupHandler().handleFinishedSnapshotTask(snapshotTask, request)) {
|
||||
AgentTaskQueue.removeTask(task.getBackendId(), TTaskType.MAKE_SNAPSHOT, task.getSignature());
|
||||
if (snapshotTask.isCopyTabletTask()) {
|
||||
snapshotTask.setResultSnapshotPath(request.getSnapshotPath());
|
||||
snapshotTask.countDown(task.getBackendId(), task.getTabletId());
|
||||
} else {
|
||||
if (Env.getCurrentEnv().getBackupHandler().handleFinishedSnapshotTask(snapshotTask, request)) {
|
||||
AgentTaskQueue.removeTask(task.getBackendId(), TTaskType.MAKE_SNAPSHOT, task.getSignature());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void finishUpload(AgentTask task, TFinishTaskRequest request) {
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.doris.qe;
|
||||
|
||||
import org.apache.doris.analysis.AdminCopyTabletStmt;
|
||||
import org.apache.doris.analysis.AdminDiagnoseTabletStmt;
|
||||
import org.apache.doris.analysis.AdminShowConfigStmt;
|
||||
import org.apache.doris.analysis.AdminShowReplicaDistributionStmt;
|
||||
@ -133,6 +134,7 @@ import org.apache.doris.common.DdlException;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.FeConstants;
|
||||
import org.apache.doris.common.MarkedCountDownLatch;
|
||||
import org.apache.doris.common.MetaNotFoundException;
|
||||
import org.apache.doris.common.PatternMatcher;
|
||||
import org.apache.doris.common.proc.BackendsProcDir;
|
||||
@ -172,8 +174,13 @@ import org.apache.doris.statistics.StatisticsJobManager;
|
||||
import org.apache.doris.system.Backend;
|
||||
import org.apache.doris.system.Diagnoser;
|
||||
import org.apache.doris.system.SystemInfoService;
|
||||
import org.apache.doris.task.AgentBatchTask;
|
||||
import org.apache.doris.task.AgentClient;
|
||||
import org.apache.doris.task.AgentTaskExecutor;
|
||||
import org.apache.doris.task.AgentTaskQueue;
|
||||
import org.apache.doris.task.SnapshotTask;
|
||||
import org.apache.doris.thrift.TCheckStorageFormatResult;
|
||||
import org.apache.doris.thrift.TTaskType;
|
||||
import org.apache.doris.thrift.TUnit;
|
||||
import org.apache.doris.transaction.GlobalTransactionMgr;
|
||||
import org.apache.doris.transaction.TransactionStatus;
|
||||
@ -199,6 +206,7 @@ import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// Execute one show statement.
|
||||
@ -361,6 +369,8 @@ public class ShowExecutor {
|
||||
handleShowCatalogs();
|
||||
} else if (stmt instanceof ShowAnalyzeStmt) {
|
||||
handleShowAnalyze();
|
||||
} else if (stmt instanceof AdminCopyTabletStmt) {
|
||||
handleCopyTablet();
|
||||
} else {
|
||||
handleEmtpy();
|
||||
}
|
||||
@ -853,7 +863,7 @@ public class ShowExecutor {
|
||||
return;
|
||||
}
|
||||
List<String> createTableStmt = Lists.newArrayList();
|
||||
Env.getDdlStmt(table, createTableStmt, null, null, false, true /* hide password */);
|
||||
Env.getDdlStmt(table, createTableStmt, null, null, false, true /* hide password */, -1L);
|
||||
if (createTableStmt.isEmpty()) {
|
||||
resultSet = new ShowResultSet(showStmt.getMetaData(), rows);
|
||||
return;
|
||||
@ -964,7 +974,7 @@ public class ShowExecutor {
|
||||
view.readLock();
|
||||
try {
|
||||
List<String> createViewStmt = Lists.newArrayList();
|
||||
Env.getDdlStmt(view, createViewStmt, null, null, false, true /* hide password */);
|
||||
Env.getDdlStmt(view, createViewStmt, null, null, false, true /* hide password */, -1L);
|
||||
if (!createViewStmt.isEmpty()) {
|
||||
rows.add(Lists.newArrayList(view.getName(), createViewStmt.get(0)));
|
||||
}
|
||||
@ -2263,9 +2273,107 @@ public class ShowExecutor {
|
||||
|
||||
private void handleShowAnalyze() throws AnalysisException {
|
||||
ShowAnalyzeStmt showStmt = (ShowAnalyzeStmt) stmt;
|
||||
StatisticsJobManager jobManager = Env.getCurrentEnv()
|
||||
.getStatisticsJobManager();
|
||||
StatisticsJobManager jobManager = Env.getCurrentEnv().getStatisticsJobManager();
|
||||
List<List<String>> results = jobManager.getAnalyzeJobInfos(showStmt);
|
||||
resultSet = new ShowResultSet(showStmt.getMetaData(), results);
|
||||
}
|
||||
|
||||
private void handleCopyTablet() throws AnalysisException {
|
||||
AdminCopyTabletStmt copyStmt = (AdminCopyTabletStmt) stmt;
|
||||
long tabletId = copyStmt.getTabletId();
|
||||
long version = copyStmt.getVersion();
|
||||
long backendId = copyStmt.getBackendId();
|
||||
|
||||
TabletInvertedIndex invertedIndex = Env.getCurrentInvertedIndex();
|
||||
TabletMeta tabletMeta = invertedIndex.getTabletMeta(tabletId);
|
||||
if (tabletMeta == null) {
|
||||
throw new AnalysisException("Unknown tablet: " + tabletId);
|
||||
}
|
||||
|
||||
// 1. find replica
|
||||
Replica replica = null;
|
||||
if (backendId != -1) {
|
||||
replica = invertedIndex.getReplica(tabletId, backendId);
|
||||
} else {
|
||||
List<Replica> replicas = invertedIndex.getReplicasByTabletId(tabletId);
|
||||
if (!replicas.isEmpty()) {
|
||||
replica = replicas.get(0);
|
||||
}
|
||||
}
|
||||
if (replica == null) {
|
||||
throw new AnalysisException("Replica not found on backend: " + backendId);
|
||||
}
|
||||
backendId = replica.getBackendId();
|
||||
Backend be = Env.getCurrentSystemInfo().getBackend(backendId);
|
||||
if (be == null || !be.isAlive()) {
|
||||
throw new AnalysisException("Unavailable backend: " + backendId);
|
||||
}
|
||||
|
||||
// 2. find version
|
||||
if (version != -1 && replica.getVersion() < version) {
|
||||
throw new AnalysisException("Version is larger than replica max version: " + replica.getVersion());
|
||||
}
|
||||
version = version == -1 ? replica.getVersion() : version;
|
||||
|
||||
// 3. get create table stmt
|
||||
Database db = Env.getCurrentInternalCatalog().getDbOrAnalysisException(tabletMeta.getDbId());
|
||||
OlapTable tbl = (OlapTable) db.getTableNullable(tabletMeta.getTableId());
|
||||
if (tbl == null) {
|
||||
throw new AnalysisException("Failed to find table: " + tabletMeta.getTableId());
|
||||
}
|
||||
|
||||
List<String> createTableStmt = Lists.newArrayList();
|
||||
tbl.readLock();
|
||||
try {
|
||||
Env.getDdlStmt(tbl, createTableStmt, null, null, false, true /* hide password */, version);
|
||||
} finally {
|
||||
tbl.readUnlock();
|
||||
}
|
||||
|
||||
// 4. create snapshot task
|
||||
SnapshotTask task = new SnapshotTask(null, backendId, tabletId, -1, tabletMeta.getDbId(),
|
||||
tabletMeta.getTableId(), tabletMeta.getPartitionId(), tabletMeta.getIndexId(), tabletId, version, 0,
|
||||
copyStmt.getExpirationMinutes() * 60 * 1000, false);
|
||||
task.setIsCopyTabletTask(true);
|
||||
MarkedCountDownLatch<Long, Long> countDownLatch = new MarkedCountDownLatch<Long, Long>(1);
|
||||
countDownLatch.addMark(backendId, tabletId);
|
||||
task.setCountDownLatch(countDownLatch);
|
||||
|
||||
// 5. send task and wait
|
||||
AgentBatchTask batchTask = new AgentBatchTask();
|
||||
batchTask.addTask(task);
|
||||
try {
|
||||
AgentTaskQueue.addBatchTask(batchTask);
|
||||
AgentTaskExecutor.submit(batchTask);
|
||||
|
||||
boolean ok = false;
|
||||
try {
|
||||
ok = countDownLatch.await(10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warn("InterruptedException: ", e);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
throw new AnalysisException(
|
||||
"Failed to make snapshot for tablet " + tabletId + " on backend: " + backendId);
|
||||
}
|
||||
|
||||
// send result
|
||||
List<List<String>> resultRowSet = Lists.newArrayList();
|
||||
List<String> row = Lists.newArrayList();
|
||||
row.add(String.valueOf(tabletId));
|
||||
row.add(String.valueOf(backendId));
|
||||
row.add(be.getHost());
|
||||
row.add(task.getResultSnapshotPath());
|
||||
row.add(String.valueOf(copyStmt.getExpirationMinutes()));
|
||||
row.add(createTableStmt.get(0));
|
||||
resultRowSet.add(row);
|
||||
|
||||
ShowResultSetMetaData showMetaData = copyStmt.getMetaData();
|
||||
resultSet = new ShowResultSet(showMetaData, resultRowSet);
|
||||
} finally {
|
||||
AgentTaskQueue.removeBatchTask(batchTask, TTaskType.MAKE_SNAPSHOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.doris.task;
|
||||
|
||||
import org.apache.doris.common.MarkedCountDownLatch;
|
||||
import org.apache.doris.thrift.TResourceInfo;
|
||||
import org.apache.doris.thrift.TSnapshotRequest;
|
||||
import org.apache.doris.thrift.TTaskType;
|
||||
@ -24,18 +25,22 @@ import org.apache.doris.thrift.TypesConstants;
|
||||
|
||||
public class SnapshotTask extends AgentTask {
|
||||
private long jobId;
|
||||
|
||||
private long version;
|
||||
|
||||
private int schemaHash;
|
||||
|
||||
private long timeoutMs;
|
||||
|
||||
private boolean isRestoreTask;
|
||||
|
||||
public SnapshotTask(TResourceInfo resourceInfo, long backendId, long signature, long jobId,
|
||||
long dbId, long tableId, long partitionId, long indexId, long tabletId,
|
||||
long version, int schemaHash, long timeoutMs, boolean isRestoreTask) {
|
||||
// Set to true if this task for AdminCopyTablet.
|
||||
// Otherwise, it is for Backup/Restore operation.
|
||||
private boolean isCopyTabletTask = false;
|
||||
private MarkedCountDownLatch<Long, Long> countDownLatch;
|
||||
// Only for copy tablet task.
|
||||
// Save the snapshot path.
|
||||
private String resultSnapshotPath;
|
||||
|
||||
public SnapshotTask(TResourceInfo resourceInfo, long backendId, long signature, long jobId, long dbId, long tableId,
|
||||
long partitionId, long indexId, long tabletId, long version, int schemaHash, long timeoutMs,
|
||||
boolean isRestoreTask) {
|
||||
super(resourceInfo, backendId, TTaskType.MAKE_SNAPSHOT, dbId, tableId, partitionId, indexId, tabletId,
|
||||
signature);
|
||||
|
||||
@ -49,6 +54,22 @@ public class SnapshotTask extends AgentTask {
|
||||
this.isRestoreTask = isRestoreTask;
|
||||
}
|
||||
|
||||
public void setIsCopyTabletTask(boolean value) {
|
||||
this.isCopyTabletTask = value;
|
||||
}
|
||||
|
||||
public boolean isCopyTabletTask() {
|
||||
return isCopyTabletTask;
|
||||
}
|
||||
|
||||
public void setCountDownLatch(MarkedCountDownLatch<Long, Long> countDownLatch) {
|
||||
this.countDownLatch = countDownLatch;
|
||||
}
|
||||
|
||||
public void countDown(long backendId, long tabletId) {
|
||||
this.countDownLatch.markedCountDown(backendId, tabletId);
|
||||
}
|
||||
|
||||
public long getJobId() {
|
||||
return jobId;
|
||||
}
|
||||
@ -69,12 +90,21 @@ public class SnapshotTask extends AgentTask {
|
||||
return isRestoreTask;
|
||||
}
|
||||
|
||||
public void setResultSnapshotPath(String resultSnapshotPath) {
|
||||
this.resultSnapshotPath = resultSnapshotPath;
|
||||
}
|
||||
|
||||
public String getResultSnapshotPath() {
|
||||
return resultSnapshotPath;
|
||||
}
|
||||
|
||||
public TSnapshotRequest toThrift() {
|
||||
TSnapshotRequest request = new TSnapshotRequest(tabletId, schemaHash);
|
||||
request.setVersion(version);
|
||||
request.setListFiles(true);
|
||||
request.setPreferredSnapshotVersion(TypesConstants.TPREFER_SNAPSHOT_REQ_VERSION);
|
||||
request.setTimeout(timeoutMs / 1000);
|
||||
request.setIsCopyTabletTask(isCopyTabletTask);
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,6 +149,7 @@ import org.apache.doris.qe.SqlModeHelper;
|
||||
keywordMap.put("connection_id", new Integer(SqlParserSymbols.KW_CONNECTION_ID));
|
||||
keywordMap.put("consistent", new Integer(SqlParserSymbols.KW_CONSISTENT));
|
||||
keywordMap.put("convert", new Integer(SqlParserSymbols.KW_CONVERT));
|
||||
keywordMap.put("copy", new Integer(SqlParserSymbols.KW_COPY));
|
||||
keywordMap.put("count", new Integer(SqlParserSymbols.KW_COUNT));
|
||||
keywordMap.put("create", new Integer(SqlParserSymbols.KW_CREATE));
|
||||
keywordMap.put("creation", new Integer(SqlParserSymbols.KW_CREATION));
|
||||
|
||||
@ -333,7 +333,7 @@ public class CreateTableAsSelectStmtTest extends TestWithFeService {
|
||||
List<String> createStmts = Lists.newArrayList();
|
||||
for (TableIf tbl : tableMap.values()) {
|
||||
List<String> createTableStmts = Lists.newArrayList();
|
||||
Env.getDdlStmt(tbl, createTableStmts, null, null, false, true);
|
||||
Env.getDdlStmt(tbl, createTableStmts, null, null, false, true, -1L);
|
||||
createStmts.add(createTableStmts.get(0));
|
||||
if (tbl.getName().equals("qs1")) {
|
||||
Assert.assertEquals("CREATE TABLE `qs1` (\n" + " `k1` int(11) NULL,\n" + " `k2` int(11) NULL\n"
|
||||
|
||||
@ -80,10 +80,11 @@ public class CreateTableLikeTest {
|
||||
private static void checkTableEqual(Table newTable, Table existedTable, int rollupSize) {
|
||||
List<String> newCreateTableStmt = Lists.newArrayList();
|
||||
List<String> newAddRollupStmt = Lists.newArrayList();
|
||||
Env.getDdlStmt(newTable, newCreateTableStmt, null, newAddRollupStmt, false, true /* hide password */);
|
||||
Env.getDdlStmt(newTable, newCreateTableStmt, null, newAddRollupStmt, false, true /* hide password */, -1L);
|
||||
List<String> existedTableStmt = Lists.newArrayList();
|
||||
List<String> existedAddRollupStmt = Lists.newArrayList();
|
||||
Env.getDdlStmt(existedTable, existedTableStmt, null, existedAddRollupStmt, false, true /* hide password */);
|
||||
Env.getDdlStmt(existedTable, existedTableStmt, null, existedAddRollupStmt, false, true /* hide password */,
|
||||
-1L);
|
||||
Assert.assertEquals(newCreateTableStmt.get(0).replace(newTable.getName(), existedTable.getName()),
|
||||
existedTableStmt.get(0));
|
||||
checkTableRollup(existedAddRollupStmt, newAddRollupStmt, newTable.getName(), existedTable.getName(),
|
||||
|
||||
@ -233,10 +233,10 @@ public class ShowExecutorTest {
|
||||
minTimes = 0;
|
||||
result = env;
|
||||
|
||||
Env.getDdlStmt((Table) any, (List) any, (List) any, (List) any, anyBoolean, anyBoolean);
|
||||
Env.getDdlStmt((Table) any, (List) any, (List) any, (List) any, anyBoolean, anyBoolean, anyLong);
|
||||
minTimes = 0;
|
||||
|
||||
Env.getDdlStmt((Table) any, (List) any, null, null, anyBoolean, anyBoolean);
|
||||
Env.getDdlStmt((Table) any, (List) any, null, null, anyBoolean, anyBoolean, anyLong);
|
||||
minTimes = 0;
|
||||
|
||||
env.getCatalogMgr();
|
||||
|
||||
Reference in New Issue
Block a user