Files
dbbackup/internal/config/profile.go
Alexander Renz 312f21bfde
All checks were successful
CI/CD / Test (push) Successful in 2m58s
CI/CD / Lint (push) Successful in 1m11s
CI/CD / Integration Tests (push) Successful in 53s
CI/CD / Native Engine Tests (push) Successful in 49s
CI/CD / Build Binary (push) Successful in 46s
CI/CD / Test Release Build (push) Successful in 1m23s
CI/CD / Release Binaries (push) Successful in 10m17s
fix(perf): use pgzip instead of standard gzip in verifyClusterArchive
- Remove compress/gzip import from internal/backup/engine.go
- Use pgzip.NewReader for parallel decompression in archive verification
- All restore paths now consistently use pgzip for parallel gzip operations

Bump version to 5.4.1
2026-02-02 11:44:13 +01:00

157 lines
5.0 KiB
Go

package config
import (
"fmt"
"strings"
)
// RestoreProfile defines resource settings for restore operations
type RestoreProfile struct {
Name string
ParallelDBs int // Number of databases to restore in parallel
Jobs int // Parallel decompression jobs
DisableProgress bool // Disable progress indicators to reduce overhead
MemoryConservative bool // Use memory-conservative settings
}
// GetRestoreProfile returns the profile settings for a given profile name
func GetRestoreProfile(profileName string) (*RestoreProfile, error) {
profileName = strings.ToLower(strings.TrimSpace(profileName))
switch profileName {
case "conservative":
return &RestoreProfile{
Name: "conservative",
ParallelDBs: 1, // Single-threaded restore
Jobs: 1, // Single-threaded decompression
DisableProgress: false,
MemoryConservative: true,
}, nil
case "balanced", "":
return &RestoreProfile{
Name: "balanced",
ParallelDBs: 0, // Use config default or auto-detect
Jobs: 0, // Use config default or auto-detect
DisableProgress: false,
MemoryConservative: false,
}, nil
case "aggressive", "performance":
return &RestoreProfile{
Name: "aggressive",
ParallelDBs: -1, // Auto-detect based on resources
Jobs: -1, // Auto-detect based on CPU
DisableProgress: false,
MemoryConservative: false,
}, nil
case "potato":
// Easter egg: same as conservative but with a fun name
return &RestoreProfile{
Name: "potato",
ParallelDBs: 1,
Jobs: 1,
DisableProgress: false,
MemoryConservative: true,
}, nil
case "turbo":
// TURBO MODE: Maximum parallelism for fastest restore
// Matches native pg_restore -j8 performance
return &RestoreProfile{
Name: "turbo",
ParallelDBs: 4, // 4 DBs in parallel (balanced I/O)
Jobs: 8, // pg_restore --jobs=8
DisableProgress: false,
MemoryConservative: false,
}, nil
case "max-performance", "maxperformance", "max":
// Maximum performance for high-end servers
// Use for dedicated restore operations where speed is critical
return &RestoreProfile{
Name: "max-performance",
ParallelDBs: 8, // 8 DBs in parallel
Jobs: 16, // pg_restore --jobs=16
DisableProgress: true, // Reduce TUI overhead
MemoryConservative: false,
}, nil
default:
return nil, fmt.Errorf("unknown profile: %s (valid: conservative, balanced, aggressive, turbo, max-performance)", profileName)
}
}
// ApplyProfile applies profile settings to config, respecting explicit user overrides
func ApplyProfile(cfg *Config, profileName string, explicitJobs, explicitParallelDBs int) error {
profile, err := GetRestoreProfile(profileName)
if err != nil {
return err
}
// Show profile being used
if cfg.Debug {
fmt.Printf("Using restore profile: %s\n", profile.Name)
if profile.MemoryConservative {
fmt.Println("Memory-conservative mode enabled")
}
}
// Apply profile settings only if not explicitly overridden
if explicitJobs == 0 && profile.Jobs > 0 {
cfg.Jobs = profile.Jobs
}
if explicitParallelDBs == 0 && profile.ParallelDBs != 0 {
cfg.ClusterParallelism = profile.ParallelDBs
}
// Store profile name
cfg.ResourceProfile = profile.Name
// Conservative profile implies large DB mode settings
if profile.MemoryConservative {
cfg.LargeDBMode = true
}
return nil
}
// GetProfileDescription returns a human-readable description of the profile
func GetProfileDescription(profileName string) string {
profile, err := GetRestoreProfile(profileName)
if err != nil {
return "Unknown profile"
}
switch profile.Name {
case "conservative":
return "Conservative: --jobs=1, single-threaded, minimal memory usage. Best for resource-constrained servers."
case "potato":
return "Potato Mode: Same as conservative, for servers running on a potato 🥔"
case "balanced":
return "Balanced: Auto-detect resources, moderate parallelism. Good default for most scenarios."
case "aggressive":
return "Aggressive: Maximum parallelism, all available resources. Best for dedicated database servers."
case "turbo":
return "Turbo: --jobs=8, 4 parallel DBs. Matches pg_restore -j8 speed. Great for production restores."
case "max-performance":
return "Max-Performance: --jobs=16, 8 parallel DBs, TUI disabled. For dedicated restore operations."
default:
return profile.Name
}
}
// ListProfiles returns a list of all available profiles with descriptions
func ListProfiles() map[string]string {
return map[string]string{
"conservative": GetProfileDescription("conservative"),
"balanced": GetProfileDescription("balanced"),
"turbo": GetProfileDescription("turbo"),
"max-performance": GetProfileDescription("max-performance"),
"aggressive": GetProfileDescription("aggressive"),
"potato": GetProfileDescription("potato"),
}
}