Skip to content

Commit

Permalink
[BugFix] Fix several problem for logical view restore
Browse files Browse the repository at this point in the history
This pr several problem:
1. analyze exception will be throw if we specify view name after ON clause.
2. can not set alias for logical view when doing restore
3. can not choice part of view to be restored, we must restored all view, this
   pr also fix this problem.
4. Forget to remove metadata for View if restore is failed.
5. do not add restore view again when replay log for restorejob.
6. pure snapshot analyze will be failed

Signed-off-by: srlch <linzichao@starrocks.com>
  • Loading branch information
srlch committed Oct 25, 2024
1 parent f15a530 commit 8e433a8
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
31 changes: 26 additions & 5 deletions fe/fe-core/src/main/java/com/starrocks/backup/BackupHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import com.starrocks.catalog.OlapTable;
import com.starrocks.catalog.Partition;
import com.starrocks.catalog.Table;
import com.starrocks.catalog.View;
import com.starrocks.common.Config;
import com.starrocks.common.DdlException;
import com.starrocks.common.ErrorCode;
Expand Down Expand Up @@ -98,6 +99,7 @@
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

import static com.starrocks.scheduler.MVActiveChecker.MV_BACKUP_INACTIVE_REASON;

Expand Down Expand Up @@ -437,14 +439,21 @@ private void restore(Repository repository, Database db, RestoreStmt stmt) throw
// Also remove all unrelated objs
Preconditions.checkState(infos.size() == 1);
BackupJobInfo jobInfo = infos.get(0);

BackupMeta backupMeta = downloadAndDeserializeMetaInfo(jobInfo, repository, stmt);

// If TableRefs is empty, it means that we do not specify any table in Restore stmt.
// So, we should restore all table in current database.
if (stmt.getTableRefs().size() != 0) {
checkAndFilterRestoreObjsExistInSnapshot(jobInfo, stmt.getTableRefs());
List<View> restoredViews = Lists.newArrayList();
if (backupMeta != null) {
if (stmt.getTableRefs().size() != 0) {
checkAndFilterRestoreObjsExistInSnapshot(jobInfo, stmt.getTableRefs(), backupMeta, restoredViews);
} else {
restoredViews = backupMeta.getTables().values().stream().filter(Table::isOlapView)
.map(x -> (View) x).collect(Collectors.toList());
}
}

BackupMeta backupMeta = downloadAndDeserializeMetaInfo(jobInfo, repository, stmt);

// Create a restore job
RestoreJob restoreJob = null;
if (backupMeta != null) {
Expand All @@ -461,6 +470,7 @@ private void restore(Repository repository, Database db, RestoreStmt stmt) throw
restoreJob = new RestoreJob(stmt.getLabel(), stmt.getBackupTimestamp(),
db.getId(), db.getOriginName(), jobInfo, stmt.allowLoad(), stmt.getReplicationNum(),
stmt.getTimeoutMs(), globalStateMgr, repository.getId(), backupMeta, mvRestoreContext);
restoreJob.setRestoredViews(restoredViews);
globalStateMgr.getEditLog().logRestoreJob(restoreJob);

// must put to dbIdToBackupOrRestoreJob after edit log, otherwise the state of job may be changed.
Expand Down Expand Up @@ -488,11 +498,22 @@ private BackupMeta downloadAndDeserializeMetaInfo(BackupJobInfo jobInfo, Reposit
return backupMetas.get(0);
}

private void checkAndFilterRestoreObjsExistInSnapshot(BackupJobInfo jobInfo, List<TableRef> tblRefs)
private void checkAndFilterRestoreObjsExistInSnapshot(BackupJobInfo jobInfo, List<TableRef> tblRefs, BackupMeta backupMeta,
List<View> restoredViews)
throws DdlException {
Set<String> allTbls = Sets.newHashSet();
for (TableRef tblRef : tblRefs) {
String tblName = tblRef.getName().getTbl();
Table tbl = backupMeta.getTable(tblName);
if (tbl != null && tbl.isOlapView()) {
if (tblRef.hasExplicitAlias()) {
// simple reset alias for view in backupMeta to be restored.
tbl.setName(tblRef.getExplicitAlias());
}
restoredViews.add((View) tbl);
continue;
}

if (!jobInfo.containsTbl(tblName)) {
ErrorReport.reportDdlException(ErrorCode.ERR_COMMON_ERROR,
"Table " + tblName + " does not exist in snapshot " + jobInfo.name);
Expand Down
10 changes: 10 additions & 0 deletions fe/fe-core/src/main/java/com/starrocks/backup/BackupJobInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,16 @@ private static void genFromJson(String json, BackupJobInfo jobInfo) {

JSONObject backupObjs = root.getJSONObject("backup_objects");
String[] tblNames = JSONObject.getNames(backupObjs);
if (tblNames == null) {
// it is possible for snapshot without any OlapTable or MV
String result = root.getString("backup_result");
if (result.equals("succeed")) {
jobInfo.success = true;
} else {
jobInfo.success = false;
}
return;
}
for (String tblName : tblNames) {
BackupTableInfo tblInfo = new BackupTableInfo();
tblInfo.name = tblName;
Expand Down
23 changes: 16 additions & 7 deletions fe/fe-core/src/main/java/com/starrocks/backup/RestoreJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ public enum RestoreJobState {
private AgentBatchTask batchTask;

boolean enableColocateRestore = Config.enable_colocate_restore;

@SerializedName(value = "restoredViews")
private List<View> restoredViews = Lists.newArrayList();

public RestoreJob() {
super(JobType.RESTORE);
Expand Down Expand Up @@ -789,9 +792,7 @@ private void checkAndPrepareMeta() {
}

// add all restored olap view into globalStateMgr
List<View> restoredOlapViews = backupMeta.getTables().values().stream().filter(Table::isOlapView)
.map(x -> (View) x).collect(Collectors.toList());
addRestoreOlapView(restoredOlapViews);
addRestoreOlapView(restoredViews);
if (!status.ok()) {
return;
}
Expand Down Expand Up @@ -1170,14 +1171,13 @@ private void replayCheckAndPrepareMeta() {
modifyInvertedIndex((OlapTable) restoreTbl, restorePart);
}
}

// restored view need not to be added again here, because
// another edit log created by createView will done.
} finally {
locker.unLockDatabase(db.getId(), LockType.WRITE);
}

List<View> restoredOlapViews = backupMeta.getTables().values().stream().filter(Table::isOlapView)
.map(x -> (View) x).collect(Collectors.toList());
addRestoreOlapView(restoredOlapViews);

LOG.info("replay check and prepare meta. {}", this);
}

Expand Down Expand Up @@ -1622,6 +1622,10 @@ private void replayWaitingAllTabletsCommitted() {
allTabletCommitted(true /* is replay */);
}

public void setRestoredViews(List<View> restoredViews) {
this.restoredViews = restoredViews;
}

public List<String> getInfo() {
List<String> info = Lists.newArrayList();
info.add(String.valueOf(jobId));
Expand Down Expand Up @@ -1740,6 +1744,11 @@ public void cancelInternal(boolean isReplay) {

restoreTbl.dropPartition(dbId, entry.second.getName(), true /* is restore */);
}

// remove restored View
for (View restoredView : restoredViews) {
db.dropTable(restoredView.getName());
}
} finally {
locker.unLockDatabase(db.getId(), LockType.WRITE);
}
Expand Down

0 comments on commit 8e433a8

Please sign in to comment.