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)
+       }
+}

Reply via email to