This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git
The following commit(s) were added to refs/heads/main by this push:
new dfd6d91f Fix restore delete wrong file issue (#838)
dfd6d91f is described below
commit dfd6d91f862f63586269c5d2265fd66a6265ef65
Author: mrproliu <[email protected]>
AuthorDate: Thu Nov 6 21:18:10 2025 +0900
Fix restore delete wrong file issue (#838)
---
banyand/backup/restore.go | 20 ++++++++++++++++++--
banyand/backup/restore_test.go | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/banyand/backup/restore.go b/banyand/backup/restore.go
index afb7f803..cac485c8 100644
--- a/banyand/backup/restore.go
+++ b/banyand/backup/restore.go
@@ -100,10 +100,13 @@ func newRunCommand() *cobra.Command {
if err = restoreCatalog(fs, timeDir,
streamRoot, commonv1.Catalog_CATALOG_STREAM); err != nil {
errs = multierr.Append(errs,
fmt.Errorf("stream restore failed: %w", err))
} else {
+ logger.Infof("delete stream
time-dir file")
_ = os.Remove(timeDirPath)
}
} else if !errors.Is(err, os.ErrNotExist) {
return err
+ } else {
+ logger.Infof("no stream time-dir file
found, skip it: %s", timeDirPath)
}
}
if measureRoot != "" {
@@ -113,10 +116,13 @@ func newRunCommand() *cobra.Command {
if err = restoreCatalog(fs, timeDir,
measureRoot, commonv1.Catalog_CATALOG_MEASURE); err != nil {
errs = multierr.Append(errs,
fmt.Errorf("measure restore failed: %w", err))
} else {
+ logger.Infof("delete measure
time-dir file")
_ = os.Remove(timeDirPath)
}
} else if !errors.Is(err, os.ErrNotExist) {
return err
+ } else {
+ logger.Infof("no measure time-dir file
found, skip it: %s", timeDirPath)
}
}
if propertyRoot != "" {
@@ -126,10 +132,13 @@ func newRunCommand() *cobra.Command {
if err = restoreCatalog(fs, timeDir,
propertyRoot, commonv1.Catalog_CATALOG_PROPERTY); err != nil {
errs = multierr.Append(errs,
fmt.Errorf("property restore failed: %w", err))
} else {
+ logger.Infof("delete property
time-dir file")
_ = os.Remove(timeDirPath)
}
} else if !errors.Is(err, os.ErrNotExist) {
return err
+ } else {
+ logger.Infof("no property time-dir file
found, skip it: %s", timeDirPath)
}
}
if traceRoot != "" {
@@ -139,10 +148,13 @@ func newRunCommand() *cobra.Command {
if err = restoreCatalog(fs, timeDir,
traceRoot, commonv1.Catalog_CATALOG_TRACE); err != nil {
errs = multierr.Append(errs,
fmt.Errorf("trace restore failed: %w", err))
} else {
+ logger.Infof("delete trace
time-dir file")
_ = os.Remove(timeDirPath)
}
} else if !errors.Is(err, os.ErrNotExist) {
return err
+ } else {
+ logger.Infof("no trace time-dir file
found, skip it: %s", timeDirPath)
}
}
@@ -182,7 +194,7 @@ func restoreCatalog(fs remote.FS, timeDir, rootPath string,
catalog commonv1.Cat
return fmt.Errorf("failed to create local directory %s: %w",
localDir, err)
}
- logger.Infof("Restoring %s to %s from %s", catalogName, localDir,
remotePrefix)
+ logger.Infof("Restoring %s to %s from %s, remote total %d files",
catalogName, localDir, remotePrefix, len(remoteFiles))
remoteRelSet := make(map[string]bool)
var relPath string
@@ -200,8 +212,10 @@ func restoreCatalog(fs remote.FS, timeDir, rootPath
string, catalog commonv1.Cat
}
for _, localRelPath := range localFiles {
- if !remoteRelSet[localRelPath] {
+ localRelPathWithCatalog := filepath.Join(catalogName,
localRelPath)
+ if !remoteRelSet[localRelPathWithCatalog] {
localPath := filepath.Join(localDir, localRelPath)
+ logger.Infof("found local file: %s not exist in the
remote storage, so delete it", localRelPathWithCatalog)
if err := os.Remove(localPath); err != nil {
return fmt.Errorf("failed to remove local file
%s: %w", localPath, err)
}
@@ -226,6 +240,8 @@ func restoreCatalog(fs remote.FS, timeDir, rootPath string,
catalog commonv1.Cat
return fmt.Errorf("failed to download %s: %w",
remoteFile, err)
}
logger.Infof("Downloaded %s to %s", remoteFile,
localPath)
+ } else {
+ logger.Infof("Skipping %s because it already exists",
remoteFile)
}
}
diff --git a/banyand/backup/restore_test.go b/banyand/backup/restore_test.go
index 5f969dc2..7454f00c 100644
--- a/banyand/backup/restore_test.go
+++ b/banyand/backup/restore_test.go
@@ -91,3 +91,41 @@ func TestRestoreDelete(t *testing.T) {
t.Fatalf("expected extra file %q to be deleted", extraFilePath)
}
}
+
+func TestRestoreSame(t *testing.T) {
+ remoteDir := t.TempDir()
+ localRestoreDir := t.TempDir()
+
+ fs, err := local.NewFS(remoteDir)
+ if err != nil {
+ t.Fatalf("failed to create remote FS: %v", err)
+ }
+
+ streamDir := filepath.Join(localRestoreDir, "stream", storage.DataDir)
+ if err = os.MkdirAll(streamDir, storage.DirPerm); err != nil {
+ t.Fatalf("failed to create local stream directory: %v", err)
+ }
+ extraFilePath := filepath.Join(streamDir, "test.txt")
+ extraContent := "hello"
+ if err = os.WriteFile(extraFilePath, []byte(extraContent), 0o600); err
!= nil {
+ t.Fatalf("failed to write extra local file: %v", err)
+ }
+
+ timeDir := "2023-10-10"
+ remoteFilePath := filepath.Join(timeDir,
snapshot.CatalogName(commonv1.Catalog_CATALOG_STREAM), "test.txt")
+ content := "hello"
+ err = fs.Upload(context.Background(), remoteFilePath,
strings.NewReader(content))
+ if err != nil {
+ t.Fatalf("failed to upload file: %v", err)
+ }
+
+ err = restoreCatalog(fs, timeDir, localRestoreDir,
commonv1.Catalog_CATALOG_STREAM)
+ if err != nil {
+ t.Fatalf("restoreCatalog failed: %v", err)
+ }
+
+ _, err = os.Stat(extraFilePath)
+ if err != nil {
+ t.Fatalf("expected extra file %q exist", extraFilePath)
+ }
+}