mirror of
https://github.com/kopia/kopia.git
synced 2026-04-16 12:07:12 -04:00
maintenance: disabled automatic compaction on repository opening
instead moved to run as part of maintenance ('kopia maintenance run')
added 'kopia maintenance run --force' flag which runs maintenance even
if not owned
This commit is contained in:
committed by
Julio López
parent
6cb970f156
commit
960c33475e
12
cli/app.go
12
cli/app.go
@@ -165,7 +165,17 @@ func maybeRunMaintenance(ctx context.Context, rep repo.Repository) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return snapshotmaintenance.Run(ctx, rep, maintenance.ModeAuto)
|
||||
err := snapshotmaintenance.Run(ctx, rep, maintenance.ModeAuto, false)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, ok := err.(maintenance.NotOwnedError); ok {
|
||||
// do not report the NotOwnedError to the user since this is automatic maintenance.
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// App returns an instance of command-line application object.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
var (
|
||||
maintenanceRunCommand = maintenanceCommands.Command("run", "Run repository maintenance").Default()
|
||||
maintenanceRunFull = maintenanceRunCommand.Flag("full", "Full maintenance").Bool()
|
||||
maintenanceRunForce = maintenanceRunCommand.Flag("force", "Run maintenance even if not owned (unsafe)").Hidden().Bool()
|
||||
)
|
||||
|
||||
func runMaintenanceCommand(ctx context.Context, rep *repo.DirectRepository) error {
|
||||
@@ -19,7 +20,7 @@ func runMaintenanceCommand(ctx context.Context, rep *repo.DirectRepository) erro
|
||||
mode = maintenance.ModeFull
|
||||
}
|
||||
|
||||
return snapshotmaintenance.Run(ctx, rep, mode)
|
||||
return snapshotmaintenance.Run(ctx, rep, mode, *maintenanceRunForce)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -267,7 +267,7 @@ func (s *Server) periodicMaintenance(ctx context.Context, r repo.Repository) {
|
||||
return
|
||||
|
||||
case <-time.After(maintenanceAttemptFrequency):
|
||||
if err := snapshotmaintenance.Run(ctx, r, maintenance.ModeAuto); err != nil {
|
||||
if err := snapshotmaintenance.Run(ctx, r, maintenance.ModeAuto, false); err != nil {
|
||||
log(ctx).Warningf("unable to run maintenance: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -722,8 +722,8 @@ func newManagerWithOptions(ctx context.Context, st blob.Storage, f *FormattingOp
|
||||
return nil, errors.Wrap(err, "unable to set up caches")
|
||||
}
|
||||
|
||||
if err := m.CompactIndexes(ctx, autoCompactionOptions); err != nil {
|
||||
return nil, errors.Wrap(err, "error initializing content manager")
|
||||
if _, _, err := m.loadPackIndexesUnlocked(ctx); err != nil {
|
||||
return nil, errors.Wrap(err, "error loading indexes")
|
||||
}
|
||||
|
||||
return m, nil
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
|
||||
const verySmallContentFraction = 20 // blobs less than 1/verySmallContentFraction of maxPackSize are considered 'very small'
|
||||
|
||||
var autoCompactionOptions = CompactOptions{
|
||||
MaxSmallBlobs: 4 * parallelFetches, // nolint:gomnd
|
||||
}
|
||||
|
||||
// CompactOptions provides options for compaction
|
||||
type CompactOptions struct {
|
||||
MaxSmallBlobs int
|
||||
|
||||
18
repo/maintenance/index_compaction.go
Normal file
18
repo/maintenance/index_compaction.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package maintenance
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/kopia/kopia/repo/content"
|
||||
)
|
||||
|
||||
const maxSmallBlobsForIndexCompaction = 8
|
||||
|
||||
// IndexCompaction rewrites index blobs to reduce their count but does not drop any contents.
|
||||
func IndexCompaction(ctx context.Context, rep MaintainableRepository) error {
|
||||
log(ctx).Infof("Compacting indexes...")
|
||||
|
||||
return rep.ContentManager().CompactIndexes(ctx, content.CompactOptions{
|
||||
MaxSmallBlobs: maxSmallBlobsForIndexCompaction,
|
||||
})
|
||||
}
|
||||
@@ -136,18 +136,28 @@ type RunParameters struct {
|
||||
Params *Params
|
||||
}
|
||||
|
||||
// NotOwnedError is returned when maintenance cannot run because it is owned by another user.
|
||||
type NotOwnedError struct {
|
||||
Owner string
|
||||
}
|
||||
|
||||
func (e NotOwnedError) Error() string {
|
||||
return "maintenance must be run by designated user: " + e.Owner
|
||||
}
|
||||
|
||||
// RunExclusive runs the provided callback if the maintenance is owned by local user and
|
||||
// lock can be acquired. Lock is passed to the function, which ensures that every call to Run()
|
||||
// is within the exclusive context.
|
||||
func RunExclusive(ctx context.Context, rep MaintainableRepository, mode Mode, cb func(runParams RunParameters) error) error {
|
||||
func RunExclusive(ctx context.Context, rep MaintainableRepository, mode Mode, force bool, cb func(runParams RunParameters) error) error {
|
||||
p, err := GetParams(ctx, rep)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to get maintenance params")
|
||||
}
|
||||
|
||||
if myUsername := rep.Username() + "@" + rep.Hostname(); p.Owner != myUsername {
|
||||
log(ctx).Debugf("maintenance owned by another user '%v'", p.Owner)
|
||||
return nil
|
||||
if !force {
|
||||
if myUsername := rep.Username() + "@" + rep.Hostname(); p.Owner != myUsername {
|
||||
return NotOwnedError{p.Owner}
|
||||
}
|
||||
}
|
||||
|
||||
if mode == ModeAuto {
|
||||
@@ -231,6 +241,13 @@ func runQuickMaintenance(ctx context.Context, runParams RunParameters) error {
|
||||
return errors.Wrap(err, "error deleting unreferenced metadata blobs")
|
||||
}
|
||||
|
||||
// consolidate many smaller indexes into fewer larger ones.
|
||||
if err := ReportRun(ctx, runParams.rep, "index-compaction", func() error {
|
||||
return IndexCompaction(ctx, runParams.rep)
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "error performing index compaction")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
)
|
||||
|
||||
// Run runs the complete snapshot and repository maintenance.
|
||||
func Run(ctx context.Context, rep repo.Repository, mode maintenance.Mode) error {
|
||||
func Run(ctx context.Context, rep repo.Repository, mode maintenance.Mode, force bool) error {
|
||||
dr, ok := rep.(*repo.DirectRepository)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return maintenance.RunExclusive(ctx, dr, mode,
|
||||
return maintenance.RunExclusive(ctx, dr, mode, force,
|
||||
func(runParams maintenance.RunParameters) error {
|
||||
// run snapshot GC before full maintenance
|
||||
if runParams.Mode == maintenance.ModeFull {
|
||||
|
||||
Reference in New Issue
Block a user