mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 00:55:55 +00:00
fsync all directories after completing a backup
Previously the backup tool only fsync'ed the files. Since the directories were not synced, it was possible for the references to be lost. Now we sync the entire output directory tree and its parent.
This commit is contained in:
parent
a8161923de
commit
779e27dcf6
1 changed files with 73 additions and 0 deletions
|
|
@ -114,6 +114,12 @@ func (cmd *BackupCommand) Run(ctx context.Context) (err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Wait for the OS to persist all directories.
|
||||
err = cmd.syncDirectories(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("syncing directories: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -367,3 +373,70 @@ func (cmd *BackupCommand) syncFile(f *os.File) error {
|
|||
func (cmd *BackupCommand) TLSHost() string { return cmd.Host }
|
||||
|
||||
func (cmd *BackupCommand) TLSConfiguration() server.TLSConfig { return cmd.TLS }
|
||||
|
||||
// syncDirectories fsyncs all directories required for the backup to be persisted to the filesystem.
|
||||
func (cmd *BackupCommand) syncDirectories(ctx context.Context) error {
|
||||
if cmd.NoSync {
|
||||
return nil
|
||||
}
|
||||
|
||||
syncChan := make(chan string, cmd.Concurrency)
|
||||
syncChan <- filepath.Dir(cmd.OutputDir)
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
for i := 0; i < cmd.Concurrency; i++ {
|
||||
g.Go(func() error {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case path, ok := <-syncChan:
|
||||
if !ok {
|
||||
return nil
|
||||
} else if err := cmd.syncDir(path); err != nil {
|
||||
return fmt.Errorf("cannot sync directory %q: %w", path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
err := filepath.Walk(cmd.OutputDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case syncChan <- path:
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
close(syncChan)
|
||||
if err != nil {
|
||||
return fmt.Errorf("walking output directory tree: %w", err)
|
||||
}
|
||||
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
func (cmd *BackupCommand) syncDir(path string) error {
|
||||
logger := cmd.Logger()
|
||||
logger.Printf("syncing directory: %s", path)
|
||||
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening directory for sync: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = f.Sync()
|
||||
if err != nil {
|
||||
return fmt.Errorf("syncing directory: %w", err)
|
||||
}
|
||||
|
||||
return f.Close()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue