diff options
author | James Fargher <jfargher@gitlab.com> | 2023-09-15 02:29:44 +0300 |
---|---|---|
committer | James Fargher <jfargher@gitlab.com> | 2023-09-15 03:12:19 +0300 |
commit | c43b91c07de39a4e32b3bb855787ab43e9c6a6c7 (patch) | |
tree | 87893b2d5f2ea14c224f89a7f6b735f393e59d1b | |
parent | 3cf5d37f61488323f55d2596e407fe41e9da23a2 (diff) |
backup: Improve time taken to create a full backup bundle
When we are creating a full backup by definition the backup should
contain all refs. So here we can reduce IO by not writing ref patterns
on a full backup.
> │ sec/op │ sec/op vs base │
> BackupRepository 96.74m ± 1% 91.94m ± 0% -4.96% (p=0.000 n=30)
Changelog: performance
-rw-r--r-- | internal/backup/backup.go | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/internal/backup/backup.go b/internal/backup/backup.go index 1e4b77b3a..614023583 100644 --- a/internal/backup/backup.go +++ b/internal/backup/backup.go @@ -328,33 +328,38 @@ func (mgr *Manager) writeBundle(ctx context.Context, repo Repository, step *Step return nil } - negatedRefs, err := mgr.negatedKnownRefs(ctx, step) - if err != nil { - return fmt.Errorf("write bundle: %w", err) - } - defer func() { - if err := negatedRefs.Close(); err != nil && returnErr == nil { - returnErr = fmt.Errorf("write bundle: %w", err) - } - }() - - patternReader, patternWriter := io.Pipe() - defer func() { - if err := patternReader.Close(); err != nil && returnErr == nil { - returnErr = fmt.Errorf("write bundle: %w", err) + var patterns io.Reader + if len(step.PreviousRefPath) > 0 { + negatedRefs, err := mgr.negatedKnownRefs(ctx, step) + if err != nil { + return fmt.Errorf("write bundle: %w", err) } - }() - go func() { - defer patternWriter.Close() + defer func() { + if err := negatedRefs.Close(); err != nil && returnErr == nil { + returnErr = fmt.Errorf("write bundle: %w", err) + } + }() - for _, ref := range refs { - _, err := fmt.Fprintln(patternWriter, ref.Name) - if err != nil { - _ = patternWriter.CloseWithError(err) - return + patternReader, patternWriter := io.Pipe() + defer func() { + if err := patternReader.Close(); err != nil && returnErr == nil { + returnErr = fmt.Errorf("write bundle: %w", err) } - } - }() + }() + go func() { + defer patternWriter.Close() + + for _, ref := range refs { + _, err := fmt.Fprintln(patternWriter, ref.Name) + if err != nil { + _ = patternWriter.CloseWithError(err) + return + } + } + }() + + patterns = io.MultiReader(negatedRefs, patternReader) + } w := NewLazyWriter(func() (io.WriteCloser, error) { return mgr.sink.GetWriter(ctx, step.BundlePath) @@ -365,7 +370,7 @@ func (mgr *Manager) writeBundle(ctx context.Context, repo Repository, step *Step } }() - if err := repo.CreateBundle(ctx, w, io.MultiReader(negatedRefs, patternReader)); err != nil { + if err := repo.CreateBundle(ctx, w, patterns); err != nil { if errors.Is(err, localrepo.ErrEmptyBundle) { return fmt.Errorf("write bundle: %w: no changes to bundle", ErrSkipped) } |